<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>RPG操作码汇总 | 樱桃小窝</title><meta name="keywords" content="AS/400"><meta name="author" content="樱桃先生"><meta name="copyright" content="樱桃先生"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="RPG操作码汇总ACQ {(E)} (Acquire)取地址位。其实400 的程序中也有指针型变量，那么也就会有地址位，这个命令是取地址位的。ADD &amp;#123;(H)&amp;#125; (Add) 加法操作  基本语法：  12Factory1 Operation Factory 2 ResultFHS01 ADD FHS02 FHS03 &#x2F;&#x2F; RPG 的语法 等价于 1EVAL FHS03&#x3D;FHS0">
<meta property="og:type" content="article">
<meta property="og:title" content="RPG操作码汇总">
<meta property="og:url" content="http://example.com/posts/b6df285e/index.html">
<meta property="og:site_name" content="樱桃小窝">
<meta property="og:description" content="RPG操作码汇总ACQ {(E)} (Acquire)取地址位。其实400 的程序中也有指针型变量，那么也就会有地址位，这个命令是取地址位的。ADD &amp;#123;(H)&amp;#125; (Add) 加法操作  基本语法：  12Factory1 Operation Factory 2 ResultFHS01 ADD FHS02 FHS03 &#x2F;&#x2F; RPG 的语法 等价于 1EVAL FHS03&#x3D;FHS0">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg">
<meta property="article:published_time" content="2020-09-28T14:41:00.000Z">
<meta property="article:modified_time" content="2022-08-27T09:38:30.024Z">
<meta property="article:author" content="樱桃先生">
<meta property="article:tag" content="AS&#x2F;400">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/posts/b6df285e/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'RPG操作码汇总',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-08-27 17:38:30'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 5.4.2"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://s2.loli.net/2022/08/20/hk9Zvq4YRsIcnrw.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">78</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">65</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">21</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间线</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/gallery/"><i class="fa-fw fas fa-camera"></i><span> 图库</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/links/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">樱桃小窝</a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间线</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/gallery/"><i class="fa-fw fas fa-camera"></i><span> 图库</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/links/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">RPG操作码汇总</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-09-28T14:41:00.000Z" title="发表于 2020-09-28 22:41:00">2020-09-28</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-08-27T09:38:30.024Z" title="更新于 2022-08-27 17:38:30">2022-08-27</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E6%8A%80%E6%9C%AF/AS-400/">AS/400</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="RPG操作码汇总"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="RPG操作码汇总"><a href="#RPG操作码汇总" class="headerlink" title="RPG操作码汇总"></a>RPG操作码汇总</h1><h2 id="ACQ-E-Acquire"><a href="#ACQ-E-Acquire" class="headerlink" title="ACQ {(E)} (Acquire)"></a>ACQ {(E)} (Acquire)</h2><p>取地址位。其实400 的程序中也有指针型变量，那么也就会有地址位，这个命令是取地址位的。<br><code>ADD &#123;(H)&#125; (Add) 加法操作</code></p>
<ol>
<li>基本语法：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory1 Operation Factory 2 Result</span><br><span class="line">FHS01 ADD FHS02 FHS03 // RPG 的语法</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">EVAL FHS03=FHS01+FHS02 //RPGLE 的语法</span><br></pre></td></tr></table></figure>

<p>FHS01、FHS02、FHS03 必须都为数字型变量（P 型，或S 型），或者就是数字意思是将Factory<br>1 项的数据，加上Factory 2 项的数据，赋值到Result 项上</p>
<ol start="2">
<li><p>语法二：<br>如果这样写的话：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory1 Operation Factory2 Result</span><br><span class="line">		 ADD      FHS02     FHS03</span><br></pre></td></tr></table></figure>
<p>就等价于：<br>EVAL FHS03=FHS03+FHS02<br>即Factory 1 项未填时，就表示将Result 项的数据，加上Factory 2 项的数据，然后赋值到Result 项上</p>
</li>
<li><p>四舍五入：<br>（H）表示四舍五入，如FHS02=12.50（4，2），FHS03=3（2，0），那么</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ADD(H) FHS02 FHS03执行之后，FHS03=16（因为进位了）</span><br></pre></td></tr></table></figure>
<p>而</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ADD FHS02 FHS03</span><br></pre></td></tr></table></figure>
<p>执行之后，FHS03=15<br>不过实际使用中，我们都尽可能使相加的字段小数位数相等，所以ADD 操作码一般都没有使用到四舍五入的功能。</p>
</li>
<li><p>可以在ADD 操作时，对Result 项的变量进行定义</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">FHS01 ADD FHS02 FHS03 10 2</span><br></pre></td></tr></table></figure>
<p>EVAL 语句不能对在赋值的同时，对变量进行定义</p>
</li>
<li><p>关于结果数据超长时的问题：<br>当加出的结果超长，比如FHS03 定义为3，2（1 位整数，2 位小数，下同）时，再假设FHS01=10，FHS02=4。那么FHS01+FHS02 本来应该等于14，但用ADD 操作之后，系统会自动将超长位截去，即FHS03 最后等于4；<br>而用EVAL 语句时，系统判断超长后，会直接报错“The target for a numeric operation is too small to hold the result”，然后异常中断。<br>使用ADD 操作码程序不会异常中断，但有可能发生了错误的数据我们也不知道；使用EVAL 操作码可以避免产生错误的数据，但程序会异常中断，需要进行人工干预。可根据实际情况选择使用ADD 还是EVAL.  </p>
</li>
</ol>
<h2 id="ADDDUR-E-Add-Duration-日期时间相加"><a href="#ADDDUR-E-Add-Duration-日期时间相加" class="headerlink" title="ADDDUR {(E)} (Add Duration) 日期时间相加"></a>ADDDUR {(E)} (Add Duration) 日期时间相加</h2><ol>
<li>对日期型变量进行加操作，比如说已定义日期型变量MYDATE1，MYDATE2，将<br>MYDATE1 的日期加上3 天，赋值到MYDATE2 中：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">MYDATE1 ADDDUR 3:*D MYDATE2</span><br></pre></td></tr></table></figure>
其中，Factory 1，Result 项，都必须为日期型变量（即在D 行，Internal Data Type项为“D” ）</li>
<li>与ADD 操作码相同，Factory 1 项为空时，表示直接在Result 项上进行日期相加，如将<br>MYDATE1 直接加上3 个月(即结果也是赋值到MYDATE1 中)：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory1 Operation Factory2 Result</span><br><span class="line">		 ADDDUR    3:*M     MYDATE1</span><br></pre></td></tr></table></figure></li>
<li>日期型变量的参数含义：</li>
</ol>
<ul>
<li>*D表示天，也可用*DAYS</li>
<li>*M表示月，也可用*MONTHS</li>
<li>*Y表示年，也可用*YEARS</li>
</ul>
<ol start="4">
<li>除了日期型之外，还有时间型，日期时间型，都可以使用ADDDUR 操作码.<br>在D 行，Internal Data Type 定义为“T”，表示时间型（时、分、秒）Internal Data Type 定义为“Z”，表示日期时间型（年、月、日、时、分、秒、微秒）在使用ADDDUR 操作码，时间型的参数如下：</li>
</ol>
<ul>
<li>*H 表示小时，也可用*HOURS</li>
<li>*MN 表示分钟，也可用*MINUTES</li>
<li>*S 表示秒， 也可用*SECONDS<br>而日期时间型，除了可以使用*Y、*M、*D、*H、*MN、*S（以及相应的全称）之外，还可以对微秒进行处理，参数为*MS，或*MSECONDS</li>
</ul>
<ol start="5">
<li>Factory 2 项中的数字，可以使用负数，使用负数时，表示减去相应的年、月、日，不过<br>通常使用SUBDUR 来进行日期的减法，语法与ADDDUR 相同</li>
</ol>
<h2 id="ANDxx-And-条件判断语句—“与”"><a href="#ANDxx-And-条件判断语句—“与”" class="headerlink" title="ANDxx (And) 条件判断语句—“与”"></a>ANDxx (And) 条件判断语句—“与”</h2><ol>
<li>在RPG 的用法中，有ANDEQ，ANDNE 之类的，与IF 语句一起联用。<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory1 Operation Factory 2 Result</span><br><span class="line">		 FLD01 IFEQ ‘A’</span><br><span class="line">		 FLD02 ANDEQ ‘B’</span><br></pre></td></tr></table></figure>
。。。处理内容<br>ENDIF</li>
<li>AND 后面跟的xx，可以有如下用法：<br>EQ Factory 1 = Factory2<br>NE Factory 1 &lt;&gt; Factory2<br>GT Factory 1 &gt; Factory2<br>LT Factory 1 &lt; Factory2<br>GE Factory 1 &gt;= Factory 2<br>LE Factory 1 &lt;= Factory 2</li>
</ol>
<h2 id="BEGSR-Beginning-of-Subroutine-子过程的开始处"><a href="#BEGSR-Beginning-of-Subroutine-子过程的开始处" class="headerlink" title="BEGSR (Beginning of Subroutine) 子过程的开始处"></a>BEGSR (Beginning of Subroutine) 子过程的开始处</h2><p>BEGSR 子过程名<br>在前面，讲述程序流程时，已经对子过程进行了解释。这里，BEGSR 本身用法没什么特别的,只是要注意有BEGSR 语句，就一定要有ENDSR 对应。否则程序编译会报错。所以这里建议，免遗漏。<br>在程序中，可以写一个子过程，但是不调用它。（也允许就是子过程没有相应的EXSR语句）也<br>允许写一个空的子过程。（也就是BEGSR 语句与ENDSR 语句之间没有别的执行语句了）</p>
<h2 id="CALL-E-Call-a-Program-调用外部程序"><a href="#CALL-E-Call-a-Program-调用外部程序" class="headerlink" title="CALL {(E)} (Call a Program) 调用外部程序"></a>CALL {(E)} (Call a Program) 调用外部程序</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory1 Operation Factory 2 Result</span><br><span class="line">		 CALL ‘外部程序名’</span><br></pre></td></tr></table></figure>
<ol>
<li><p>如果是直接调用外部程序，那么程序名称需要用单引号括起来，且该程序必须存在。如<br>CALL ‘FHSILE01’<br>就表示调用“FHSILE01”这个外部程序</p>
</li>
<li><p>如果没有用单引号，如<br>CALL FHSILE01<br>就表示，FHSILE01 这时是个字符型变量（即并非调用“FHSILE01 这个程序），调用的是<br>变量内容所代表的程序。如：<br>FHSILE01=’FHS01’时，表示调用“FHS01”这个外部程序；<br>FHSILE01=’FHS02’时，表示调用“FHS02”这外外部程序<br>也就是说，CALL 操作码调用的程序名，可以是一个变量名。</p>
</li>
<li><p>被调用的外部程序如果有接口参数，那么CALL 操作码之后，也需要有“PARM”操作码相对应。</p>
</li>
<li><p>这一点要注意：虽然400 的程序段代码中，是不区分大小写；但调用的程序名，要区分大<br>写小。即’FHSILE01’，与fhsile01，表示的是两个不同的程序。在使用时要注意，尤其<br>是程序名使用字符变量来表达时，可能会因为大小写的问题而导致 CALL 不到想CALL 的程<br>序，从而导致程序异常中断</p>
</li>
</ol>
<h2 id="CASxx-Conditionally-Invoke-Subroutine-带条件的调用子过程"><a href="#CASxx-Conditionally-Invoke-Subroutine-带条件的调用子过程" class="headerlink" title="CASxx (Conditionally Invoke Subroutine) 带条件的调用子过程"></a>CASxx (Conditionally Invoke Subroutine) 带条件的调用子过程</h2><ol>
<li>表示根据xx 项对Factory 1 与Factory 2 进行判断，当符合条件时，执行Result 处的子<br>过程。需要配合“END”或“ENDCS”语句来表示条件判断的结束。不需要“SELECT”操作<br>码。</li>
<li>举例如下：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">		  FLD01 CASEQ ‘1’ SUB01</span><br><span class="line">	 	  FLD01 CASEQ ‘2’ SUB02</span><br><span class="line">		  CAS SUB03</span><br><span class="line">ENDCS</span><br></pre></td></tr></table></figure>
表示当FLD01 等于’1’时，执行子过程SUB01；<br>当FLD01 等于’2’时，执行子过程SUB02；<br>当不满足以上两个条件时，执行子过程SUB03<br>最后的“ENDCS”必须要有，表示条件判断结束；但不需要SELECT。上面这段语句，与下面<br>这一段是等价的：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">SELECT</span><br><span class="line">WHEN FLD01=’1’</span><br><span class="line">EXSR SUB01</span><br><span class="line">WHEN FLD01=’2’</span><br><span class="line">EXSR SUB02</span><br><span class="line">OTHER</span><br><span class="line">EXSR SUB03</span><br><span class="line">ENDSL</span><br></pre></td></tr></table></figure></li>
<li>可以看出来，CASxx 这种语句，是用于逻辑判断仅一个条件时的分支处理，这样的写法在代<br>码的阅读上会很直观。而当逻辑判断大于一个条件时，这个语句就不适用了。</li>
</ol>
<h2 id="CAT-P-Concatenate-Two-Character-Strings-字符连接"><a href="#CAT-P-Concatenate-Two-Character-Strings-字符连接" class="headerlink" title="CAT {(P)} (Concatenate Two Character Strings) 字符连接"></a>CAT {(P)} (Concatenate Two Character Strings) 字符连接</h2><ol>
<li>基本语法：<br>Factory 1 Operation Factory 2 Result<br>FLD01 CAT FLD02:0 FLD03<br>这句话的意思，是将FLD02 拼在FLD01 后面，中间没有空格，然后将拼出的结果赋值到FLD03<br>中。<br>FLD02：0，表示FLD02 与FLD01 之间的空格数为0，依此类推<br>FLD02：1，就表示FLD01 后面加一个空格，再拼上FLD02<br>FLD02：3，就表示FLD01 后面加三个空格，再拼上FLD02<br>Factory 1 项，与Factory 2 项可以是字符型变量，也可以就是字符。当是字符时，需要<br>用单引号将字符括起来</li>
<li>其实根据RPG 的语法，Factory1 项如果不填值，就表示将Factory 2 项的内容直接拼在Result 项上，这里就不举例了。</li>
<li>字段FLD01 如果内容后面有空格，如“ABC ”，那么在CAT 操作时，系统会自动将后面的空格截去，只取’ABC’。举例：<br>FLD01=’ABC ‘ （8 位字符型），<br>FLD02=’1’ （1 位字符型），<br>FLD03=’’ （8 位字符型）<br>那么，执行了下述语句之后<br>FLD01 CAT FLD02:0 FLD03<br>FLD03 就等于’ABC1 ’<br>而如果执行：<br>FLD01 CAT FLD02:1 FLD03<br>FLD03 就等于’ABC 1 ‘ （C 与1 之间有一个空格）</li>
<li>表示空格个数时，可以使用数字型的变量来表达，如<br>EVAL N=1<br>FLD01 CAT FLD02:N FLD03</li>
<li>CAT 操作码，其实也可以通过EVAL 来实现部分。比如将FLD01 与FLD02 拼起来，中间无空格，赋值到FLD03 中，也可以写做：<br>EVAL FLD03=FLD01 + FLD02</li>
<li>EVAL 操作码的优势，在于可以在一行语句中，就把多个字符拼在一起，如：<br>EVAL FLD05=FLD01+FLD02+FLD03+FLD04</li>
<li>EVAL 操作码的不足之处，在于只能进行最简单的拼接，无法自动将字符后面的空格去除，如：<br>FLD01=’ABC ‘ （8 位字符型），<br>FLD02=’1’ （1 位字符型），<br>FLD03=’’ （8 位字符型）<br>在执行语句EVAL FLD03=FLD01+FLD02<br>后，<br>FLD03=’ABC ‘<br>因为FLD01 是8 位，FLD03 也是8 位，在操作时，不能去掉ABC 后面的5 位空格，此时后面再<br>拼FLD02 已无意义，所以FLD03 仍是’ABC ‘</li>
</ol>
<h2 id="CHAIN-N-E-Random-Retrieval-from-a-File-按键值对文件记录进行查询定位"><a href="#CHAIN-N-E-Random-Retrieval-from-a-File-按键值对文件记录进行查询定位" class="headerlink" title="CHAIN {(N | E)} (Random Retrieval from a File) 按键值对文件记录进行查询定位"></a>CHAIN {(N | E)} (Random Retrieval from a File) 按键值对文件记录进行查询定位</h2><ol>
<li><p>基本语法：<br>举例，对逻辑文件PFFHSL1 进行定位操作。逻辑文件PFFHSL1，是以FHS01 为键值，文件记<br>录格式名叫FMTFHS</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FHS01	  CHAIN  	FMTFHS 			 17 18</span><br></pre></td></tr></table></figure>
<p>这个例子中，FHS01 应该是一个与文件PFFHSL1 中键值（FLD01）类型、长度都<br>相等的一个字符型变量，或者字符。<br>Factory 2 项中，要填文件的记录格式名，而不是文件名<br>HI 指示器表示是否查询到相应记录，查询不成功时，打开HI 指示器<br>LO 指示器表示查询时，文件是否被锁。文件被锁时，打开LO 指示器<br>也就是说：<br>*IN17=’0’，表示查询到了对象记录。<br>*IN17=’1’, *IN18=’0’，表示无相应的对象记录<br>*IN17=’1’, *IN18=’1’， 表示查询时，文件被锁（不确定有没有相应的对象记录）</p>
</li>
<li><p>用修改方式声明的文件，当查询成功后，对象记录被锁定，其它程序无法以修改的方式定位<br>到当前对象记录上。（但可以用只读的方式定位）</p>
</li>
<li><p>LO 指示器，仅于用修改方式声明的文件。对于只读方式声明的文件其实无意义</p>
</li>
<li><p>如果用修改方式声明文件，但在LO 处未填写指示器，且有程序锁住对象记录时，当前程序会根据PF 中定义的WAITRCD(Maximum record wait time)参数，等待相应的秒数(如WAITRCD处为10，即表示锁表时，等待10 秒；如果填的是*IMMED，就表示不等待，一判断对象记录被锁就结束操作)；如果在等待时间内，对方仍未解锁，当前程序就会异常中断退出；如果LO 处填写指示器，那么程序就不会中断退出，且LO 指示器打开。</p>
</li>
<li><p>当FHS01 键值，在文件PFFHSL1 中，对应有多条记录时（即键值不唯一），程序将会按照文件的内部记录号由小到大的顺序，定位到符合条件的第一条记录。</p>
</li>
<li><p>当一个逻辑文件，KEY 值有多项时，可以使用KLIST 操作码先定义一个组合键值，然后再用<br>这个组合键值来进行CHAIN 操作。需要注意，组合键值中，必须每一个成员字段都与对象记录<br>所对应的字段相等，才能查询成功。（所以组合键值，通常使用SETLL 定位较多）</p>
</li>
<li><p>当用修改方式声明文件，但希望进行不锁记录的查询操作时，可以将CHAIN 操作码写为CHAIN（N），这个括号（N），就表示当前的查询定位，不对记录进行锁定操作（也就是用只读的方式来处理对象记录，所以只能取出对象记录的信息，不能做修改；如果要修改对象记录的话，还必须进行一个CHAIN 操作）</p>
</li>
<li><p>这一条要特别注意：当没有填写HI 指示器时，RPGLE 是允许编译通过的。而在某些情况之下，运行程序时，如果CHIAN操作成功，找到了符合条件的记录时，没有任何问题；但如果CHAIN 操作没有找到符合条件的记录时，实际上系统会按照键值的排序以及内部记录号，定位到下一条记录上，这时再取出来的数据，就统统都是下一条记录的数据。所以，除非有绝对的把握，CHAIN 操作肯定成功，否则就一定要养成填写HI 指示器的良好习惯。</p>
</li>
</ol>
<h2 id="CHECK-E-Check-Characters-检查对象变量中的字符"><a href="#CHECK-E-Check-Characters-检查对象变量中的字符" class="headerlink" title="CHECK {(E)} (Check Characters) 检查对象变量中的字符"></a>CHECK {(E)} (Check Characters) 检查对象变量中的字符</h2><ol>
<li>基本语法：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">    FLD01 CHECK     FLD02:2   N      42</span><br></pre></td></tr></table></figure>
语句CHECK 的意思，是指字段FLD02 中，从第二位字符开始，向右查找(含第二位字符)，是否包含有FLD01 中没有的字符。<br>如果的确有在FLD01 中没有的字符，将字符所在位置赋值到变量N 中，同时打开EQ 指示器；\如果从第二位字开始，向右读取的所有字符，都可以在变量FLD01 中找到，那么N 为0，EQ<br>指示器处于关闭状态。<br>“FLD02:2”表示从变量FLD02 的第二位开始，向右作比较。如果仅仅只是“FLD02”，那么就表示从变量FLD02 的首位开始，向右查找</li>
<li>实例<br>假设FLD01 为8 位长字符，且当前值为’12345678’<br>而FLD02 为5 位长字符，且当前值为’A3456’<br>那么执行上述CHECK 操作后，N=0， *IN42=’0’（从第二位开始，3456 都存在于变量FLD01<br>中）<br>假设FLD01 为8 位长字符，且当前值为’12345678’<br>而FLD02 为5 位长字符，且当前值为’34ABDC’<br>那么执行CHECK 操作后，N=3 *IN42=’1’ (即第三位“A”， 不存在于变量FLD01 中)</li>
</ol>
<h2 id="CHECKR-E-Check-Reverse-反向检查对象变量中的字符"><a href="#CHECKR-E-Check-Reverse-反向检查对象变量中的字符" class="headerlink" title="CHECKR {(E)} (Check Reverse) 反向检查对象变量中的字符"></a>CHECKR {(E)} (Check Reverse) 反向检查对象变量中的字符</h2><ol>
<li><p>基本语法：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01     CHECKR    FLD02:3   N      42</span><br></pre></td></tr></table></figure>
<p>语句CHECKR 的意思，是指字段FLD02 中，从第三位字符开始，向左查找(含第三位字符)，是否包含有FLD01 中没有的字符。（基本与CHECK 类似，所不同的，就是CHECK 是自左向右的查找；而CHECKR 是自右向左查找）如果有，将字符所在位置赋值到变量N 中，同时打开EQ 指示器；如果从第二位字开始，向左读取的所有字符，都可以在变量FLD01 中找到，那么N 为0，EQ指示器处于关闭状态。“FLD02:3”表示从变量FLD02 的第三位开始，向左作比较。如果仅仅只是“FLD02”，那么就表示从变量FLD02 的末位开始，向左查找</p>
</li>
<li><p>实例<br>假设FLD01 为8 位长字符，且当前值为’12345678’而FLD02 为5 位长字符，且当前值为’23A56’<br>那么执行上述CHECK 操作后，N=0， *IN42=’0’（从第三位开始，向左，23 都存在于变量FLD01 中）<br>假设FLD01 为8 位长字符，且当前值为’12345678’<br>而FLD02 为5 位长字符，且当前值为’BC3B45’<br>那么执行CHECK 操作后，N=2，*IN42=’1’ (即第二位“C”，不存在于变量FLD01中)</p>
</li>
<li><p>计算字符实际长段<br>根据CHECKR 的这个操作码的用法，我们可以使用它来取出变量截去尾部空格后的实际长度：<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>‘ ‘         CHECKR        FLD02      N        42<br>Factory 1 项，是一个空格字符。<br>N 表示的意思是：从变量FLD02 的尾部，向前数第一个非空格字符，在FLD02 中所处的位置。<br>那么这个N 当然就是变量FLD02 的实际长度；<br>如果指示器未打开，那么说明整行都是空，实际长度为0，也没错。</p>
</li>
</ol>
<h2 id="CLEAR-Clear-清除内容"><a href="#CLEAR-Clear-清除内容" class="headerlink" title="CLEAR (Clear) 清除内容"></a>CLEAR (Clear) 清除内容</h2><ol>
<li>基本语法<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">		CLEAR 对象名</span><br></pre></td></tr></table></figure>
这个对象名，可以是程序中定义的结构、文件的记录格式名。<br>所谓文件的记录格式名，包括了程序中声明的磁盘文件、打印报表文件、屏幕文件CLEAR操作的意思，就是将对象所对应的所有变量/字段都赋上空值</li>
</ol>
<h2 id="CLOSE-E-Close-Files-关闭文件"><a href="#CLOSE-E-Close-Files-关闭文件" class="headerlink" title="CLOSE {(E)} (Close Files) 关闭文件"></a>CLOSE {(E)} (Close Files) 关闭文件</h2><ol>
<li>基本语法<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">		  CLOSE     对象文件名</span><br></pre></td></tr></table></figure></li>
<li>CLOSE 所对应的，是文件名，不是文件的记录格式名，要注意</li>
<li>CLOSE 操作码，仅适用于声明文件时，keyword 使用“USROPN”关键字的文件</li>
<li>每一个CLOSE 的操作，在之前都必须有OPEN 文件的操作。也就是，文件必须打开了之后，才能关闭。不能关闭未打开的文件</li>
<li>允许使用*ALL 变量，来表达关闭所有已打开的文件：</li>
</ol>
<h2 id="COMMIT-E-Commit-日志事务处理的确认操作"><a href="#COMMIT-E-Commit-日志事务处理的确认操作" class="headerlink" title="COMMIT {(E)} (Commit) 日志事务处理的确认操作"></a>COMMIT {(E)} (Commit) 日志事务处理的确认操作</h2><ol>
<li>基本语法<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">          COMMIT</span><br></pre></td></tr></table></figure></li>
<li>该操作码无其它参数，就是指对事务处理进行确认操作。</li>
<li>ILE 程序中，COMMIT 操作可随时进行，也允许在没有声明COMMIT 类型的文件的情况下，仍进行COMMIT 操作（对该进程这前的事务进行确认处理）</li>
<li>关于日志的确认操作，在后面会另设专门章节讲述</li>
</ol>
<h2 id="COMP-Compare-比较"><a href="#COMP-Compare-比较" class="headerlink" title="COMP (Compare) 比较"></a>COMP (Compare) 比较</h2><ol>
<li>基本语法：<br>将Factory 1 与Factory 2 进行比较。<br>当Factory 1 &gt; Factory 2 时，打开HI 指示器；<br>当Factory 1 = Factory 2 时，打开LO 指示器；<br>当Factory 1 &lt; Factory 2 时，打开EQ 指示器。<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01     COMP      FLD02            56 57 58</span><br></pre></td></tr></table></figure>
当FLD01=2，FLD02=1 时，*IN56=’1’， *IN57=’0’, *IN58=’0’<br>当FLD01=2，FLD02=2 时，*IN56=’0’, *IN57=’0’, *IN58=’1’<br>当FLD01=1，FLD02=2 时，*IN56=’0’, *IN57=’1’, *IN58=’0’</li>
</ol>
<h2 id="DEFINE-Field-Definition"><a href="#DEFINE-Field-Definition" class="headerlink" title="DEFINE (Field Definition)"></a>DEFINE (Field Definition)</h2><p>根据已知的字段，来定义新字段，如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">*LIKE     DEFINE    FLD01     FLD02</span><br></pre></td></tr></table></figure>
<p>这句话的意思，就是说“象定义字段FLD01 一样，定义字段FLD02 的类型、长度”这个字段FLD01,必须是个已定义的字段/变量</p>
<h2 id="DELETE-E-Delete-Record"><a href="#DELETE-E-Delete-Record" class="headerlink" title="DELETE {(E)} (Delete Record)"></a>DELETE {(E)} (Delete Record)</h2><p>删除当前记录，语法如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  DELETE    文件记录格式名</span><br></pre></td></tr></table></figure>
<p>这里，在做DELETE 操作前，必须先定位到具体的记录上（使用CHAIN、READ 等语句）；同时，文件在F 行必须使用修改的方式来声明。当文件定位到对象记录时，对象记录会被锁定，此时，对象记录无法被其它程序修改；</p>
<p>如果执行了DELETE 操作，自然会解锁，不过别的程序也找不到对象记录了（因为被删除）实际使用中，通常并不会对文件中的记录进行物理删除，而是修改某个标识状态的字段的值，所以使用这条命令要慎重</p>
<h2 id="DIV-H-Divide-数学运算—除"><a href="#DIV-H-Divide-数学运算—除" class="headerlink" title="DIV {(H)} (Divide) 数学运算—除"></a>DIV {(H)} (Divide) 数学运算—除</h2><p>DIV 操作码，表示数学运算的“除”，常与操作码MVR 一起来使用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01     DIV       FLD02     N</span><br><span class="line">MVR M</span><br></pre></td></tr></table></figure>
<p>上面两句话的意思，是说，用FLD01 来除FLD02，将商赋值到变量N 中，将余数，赋值到变量中。<br>(N，M 都是数字型变量)再具体一点，如果FLD01 = 10, FLD02 = 3，执行完这两句操作码之后<br>N = 3 （10 / 3 的商）<br>M = 1 （10 / 3 的余数）</p>
<h2 id="DO-Do-循环"><a href="#DO-Do-循环" class="headerlink" title="DO (Do) 循环"></a>DO (Do) 循环</h2><p>最常用的循环方法之一，适用于已知循环次数的循环，与ENDDO 搭配使用，每一个DO，必须要配合一个ENDDO。基本语法如下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1         DO        10</span><br></pre></td></tr></table></figure>
<p>循环中处理的内容<br>ENDDO<br>上面的意思，就是说固定循环10 次。<br>不过呢，在实际使用中，我们常常需要知道当前循环到了第几次处理，这里，可以：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1         DO        10        N</span><br></pre></td></tr></table></figure>
<p>处理过程<br>ENDDO<br>这个N，是一个整数型变量（小数位为0 的P 型吧），它所表示的就是循环的次数。如第一次循环，N=1；第二次循环，N=2所以， 1 DO 1，就表示只循环一次，而不是表示死循环。</p>
<h2 id="DOU-M-R-Do-Until-还是循环"><a href="#DOU-M-R-Do-Until-还是循环" class="headerlink" title="DOU {(M | R)} (Do Until) 还是循环"></a>DOU {(M | R)} (Do Until) 还是循环</h2><p>也是循环，不过当满足Extend Factory 2 项的条件之后，结束循环。如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">          DOU       FLD01&gt;FLD02</span><br></pre></td></tr></table></figure>
<p>处理过程<br>ENDDO<br>上面这句话，就是说当FLD01 小于或等于FLD02 时，进行循环；当满足条件，即FLD01大于FLD02时，结束循环。在RPGLE 的写法中，这个条件可以写得很复杂。当然，很复杂的时候，要记得多括号，以免得逻辑判断与设计不一致。</p>
<h2 id="DOUxx-Do-Until-又是循环"><a href="#DOUxx-Do-Until-又是循环" class="headerlink" title="DOUxx (Do Until) 又是循环"></a>DOUxx (Do Until) 又是循环</h2><p>这应该是RPG 的写法，上面的循环也可以写做：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">FLD01 DOUGT FLD02</span><br><span class="line">ENDDO</span><br></pre></td></tr></table></figure>
<p>不过，正如果前面所说的“ANDxx”操作码一样，RPGLE 的表示手法可以比RPG 更直观，更好维护，所以这里也是一样的原理，有了“DOU”之后，我们就可以不用“DOUxx”了  </p>
<h2 id="DOW-M-R-Do-While-循环，又见循环"><a href="#DOW-M-R-Do-While-循环，又见循环" class="headerlink" title="DOW {(M | R)} (Do While) 循环，又见循环"></a>DOW {(M | R)} (Do While) 循环，又见循环</h2><p>这个循环的意思，与DOU 正好相反，它的意思是满足Extend Fatcory 2 项的条件时，才进行循环，不满足条件时，不循环</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">          DOW       FLD01&gt;FLD02</span><br></pre></td></tr></table></figure>
<p>处理过程<br>ENDDO<br>上面这句话，就是说当FLD01 小于或等于FLD02 时，不进行循环循环；当满足条件，即FLD01 大于FLD02 时，才进行循环。在RPGLE 的写法中，这个条件可以写得很复杂。当然，很复杂的时候，要记得多用括号，以免得逻辑判断与设计不一致。<br>注意：在实际使用过程中，我常常只使用DO，DOW 这两种循环。而且使用DOW 时，常常使其条件永远成立（即死循环，比如说1=1 就永远成立，那么 DOW 1=1 就是个死循环），然后在循环体中用IF 语句判断何时退出循环（使用LEAVE 语句），我认为这样会比较直观，而且很少会在逻辑上出错。<br>DOWxx (Do While) 最后一个循环了<br>跟 DOU 与DOUxx 的关系一样，有了DOW 之后，就不需要DOWxx 了，不多说了。</p>
<h2 id="DSPLY-E-Display-Function-屏幕显示"><a href="#DSPLY-E-Display-Function-屏幕显示" class="headerlink" title="DSPLY {(E)} (Display Function) 屏幕显示"></a>DSPLY {(E)} (Display Function) 屏幕显示</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01     DSPLY</span><br></pre></td></tr></table></figure>
<p>就是在屏幕上，显示FLD01 的内容。FLD01 可以是字符、数字型变量。也可以直接就是字符、数字。<br>ELSE (Else) 逻辑判断语句<br>常见用法：<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>IF 条件判断<br>处理内容一<br>ELSE<br>处理内容二<br>ENDIF</p>
<p>不满足条件判断的时候，就执行ELSE 与ENDIF 之间的处理内容二；<br>满足条件判断时，执行IF 与ELSE 之间的处理内容一。<br>IF 与它最临近的ELSE、ENDIF 配对；<br>同理，ELSE 也是与它最临近的IF、ENDIF 配对。<br>注意多层IF 嵌套时的逻辑判断，这个要自己多尝试，不讲了。<br>ELSEIF {(M | R)} (Else/If) 逻辑判断语句<br>与ELSE 类似，不过将条件判断语句也写在了同一行。<br>ELSEIF 不需要相应的ENDIF 语句。即<br>IF 条件判断1<br>处理内容一<br>ELSEIF 条件判断2<br>处理内容二<br>ELSE<br>处理内容三<br>ENDIF<br>当程序满足条件判断1，将执行IF 与ELSEIF 之间的处理内容一；<br>当程序不满足条件判断1，满足条件判断2，执行ELSEIF 与ELSE 之间的处理内容二；<br>当程序连条件判断2 的内容都不满足时，执行ELSE 与ENDIF 之间的内容处理内容三。<br>也就是说，这时的ELSE，是和ELSEIF 进行配对的，要注意。<br>ENDyy (End a Structured Group)<br>ENDIF 对应 IF、IFxx<br>ENDSR 对应 BEGSR<br>ENDDO 对应 DO、DOW、DOU、DOUxx、DOWxx<br>ENDSC 对应 CASxx<br>ENDSL 对应 SELECT<br>ENDFOR 对应 FOR<br>ENDSR (End of Subroutine) 子过程结束语句</p>
<h2 id="EVAL-H-M-R-Evaluation-赋值语句"><a href="#EVAL-H-M-R-Evaluation-赋值语句" class="headerlink" title="EVAL {(H | M | R)} (Evaluation) 赋值语句"></a>EVAL {(H | M | R)} (Evaluation) 赋值语句</h2><ol>
<li><p>基本语法：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">EVAL FLD01=FLD02</span><br></pre></td></tr></table></figure>
<p>赋值，使用FLD01 的值，等于FLD02 的值。FLD01 与FLD02 的类型必须相同（即<br>同为字符型，或同为数字型，但长度可以不同。</p>
</li>
<li><p>当FLD01、FLD02 同为字符型时，EVAL 语句其实等价于：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">EVAL FLD01=\*BLANKS</span><br><span class="line">MOVEL FLD02 FLD01</span><br></pre></td></tr></table></figure>
<p>即先清空FLD01（当FLD01 长度长于FLD02，且有初始值时，这个操作就有意义了），然后再将FLD02 左对齐赋值到FLD01 中。所谓左对齐的含义，就是说将FLD02 至左向右（含空字符），依次向FLD01 字段中赋值。当FLD02 长度大于FLD01 时，右边的字符在赋值时将会被截去。</p>
</li>
<li><p>当FLD01、FLD02 同为数字型时，且FLD02 的值，超过FLD01 的长度时，EVAL语句会直接报错，程序异常中断；</p>
</li>
<li><p>当FLD01、FLD02 同为字符型时，且FLD01 的长度大于FLD02 时，将会将FLD02的值左对齐赋值到FLD01 中，并且将后面内容全部清空。<br>比如FLD01=’12345678’（8 位字符型），FLD02=’54321’（5 位字符型）执行了 EVAL FLD01=FLD02<br>之后，FLD01=’54321 ‘</p>
</li>
<li><p>当FLD01、FLD02 同为字符型，且FLD01 的长度小于FLD02 时，会将FLD02 的内容左对齐，再赋值到FLD02 中。</p>
</li>
<li><p>字符的拼接：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">          EVAL FLD01=FLD02+FLD03+’AAA’+’BB’+FLD04</span><br></pre></td></tr></table></figure>
<p>FLD01、FLD02、FLD03、FLD04 都必须是字符。FLD02、FLD03 如果字符未满，有空格，EVAL 操<br>作码不会将空格去掉。如果太长，可以分多行写，“+ ”在上在下都可。即</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">EVAL FLD01 = FLD02 +</span><br><span class="line">    FLD03</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">EVAL FLD01 = FLD02</span><br><span class="line">     + FLD03</span><br></pre></td></tr></table></figure></li>
<li><p>数学运算：<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>EVAL FLD01 =(((LD02+FLD03）* FLD04) / 2) - FLD05<br>加、减、乘、除都在了。注意多用括号。<br>如果运算公式太长，一行写不完，也可以分行写，运算符在上行、下行都可以。</p>
</li>
<li><p>四舍五入：<br>对于数字运算，EVAL(H)，是四舍五入的运算，如<br>EVAL(H) FLD01 = FLD02 / FLD03<br>而EVAL，仅仅只是四舍，没有五入。<br>EXFMT {(E)} (Write/Then Read Format) 显示屏幕文件并等待输入<br>这个操作码的意思，是显示屏幕，并等待输入，语法为：</p>
</li>
</ol>
<h2 id="Factory-1-Operation-Factory-2-Result-HI-LO-EQ"><a href="#Factory-1-Operation-Factory-2-Result-HI-LO-EQ" class="headerlink" title="Factory 1 Operation Factory 2 Result HI LO EQ"></a>Factory 1 Operation Factory 2 Result HI LO EQ</h2><p>EXFMT 记录格式名<br>当程序执行到这一句时，表示显示“记录格式名”所对应的子文件（由DSPF 定义，显示在屏幕上），同时等待用户进行输入操作</p>
<p>当用户输入预定义的热键（F3，F4 等等）、或执行输入操作后(按下输入键)，程序才会继续向下执行。</p>
<h2 id="EXSR-Invoke-Subroutine-执行子过程"><a href="#EXSR-Invoke-Subroutine-执行子过程" class="headerlink" title="EXSR (Invoke Subroutine) 执行子过程"></a>EXSR (Invoke Subroutine) 执行子过程</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  EXSR 		子过程名</span><br></pre></td></tr></table></figure>
<h2 id="EXTRCT-E-Extract-Date-Time-取日期、时间型变量中的具体内容"><a href="#EXTRCT-E-Extract-Date-Time-取日期、时间型变量中的具体内容" class="headerlink" title="EXTRCT {(E)}(Extract Date/Time) 取日期、时间型变量中的具体内容"></a>EXTRCT {(E)}(Extract Date/Time) 取日期、时间型变量中的具体内容</h2><p>首先，必须要有一个日期或时间型变量，这个可以在D 行定义，然后使用该变量中有值，比如<br>D FLD01 S D<br>D FLD02 S T<br>C MOVE *DATE FLD01<br>C TIME FLD02<br>这样，就有了一个日期型变量FLD01，一个时间型变量FLD02，且两个变量中都有值。再假设变量FLDYEAR 为四位字符型、FLDHOUR 为两位数字型</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">EXTRCT FLD01:\*Y FLDYEAR</span><br><span class="line">EXTRCT FLD02:\*H FLDHOUR</span><br></pre></td></tr></table></figure>
<p>这时，FLDYEAR 表示当前的年份；FLDHOUR 表示当前的小时所以说，EXTRCT 操作码对应的对象变量，可以是字符型，也可以是数字型，但长度一定要与预期的对象长度相等（比如年份可以是字符，也可以是数字，但长度必须为4 位；月份必须为2 位，依此类推）而冒号后面所跟的参数，与ADDDUR 操作码一样，如下：<br>对应于日期型变量：<br>*D表示天，也可用*DAYS<br>*M表示月，也可用*MONTHS<br>*Y表示年，也可用*YEARS<br>对应于时间型变量<br>*H 表示小时，也可用*HOURS<br>*MN 表示分钟，也可用*MINUTES<br>*S 表示秒， 也可用*SECONDS</p>
<h2 id="FOR-For-又是循环"><a href="#FOR-For-又是循环" class="headerlink" title="FOR (For) 又是循环"></a>FOR (For) 又是循环</h2><p>FOR 操作码，也是一种指定次数的循环，与“DO”循环有异曲同工之妙。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  FOR 				  N=1       TO 10</span><br></pre></td></tr></table></figure>
<p>处理语句<br>ENDFOR<br>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1 		  DO 		10 		  N</span><br><span class="line">		  处理语句</span><br><span class="line"></span><br><span class="line">		  ENDDO</span><br></pre></td></tr></table></figure>
<p>都是循环10 次，并且将当前循环次数赋值到数字型变量N 中<br>GOTO (Go To) 跳转语句<br>GOTO，跳转语句。跳转到指定的标签处，需要用“TAG”语句来定义，如：<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>处理语句1<br>IF 条件判断<br>GOTO FHSTAG<br>ENDIF<br>处理语句2<br>FHSTAG TAG<br>在这里，执行完处理语句1 时，如果“条件判断”成立，将会直接跳至“FHSTAG TAG”处，不<br>执行处理语句2。主过程不能跳转至子过程；（主过程我用来表示是与子过程相对应的词，指C 行<br>顺序第一行，至程序结束语句之间的语句）子过程不能跳转至其它子过程，只能在本子过程内<br>部跳转，或跳转到主过程；技术可以使用跳转语句来实现循环，不过不建议。</p>
<h2 id="IF-M-R-If-条件判断"><a href="#IF-M-R-If-条件判断" class="headerlink" title="IF {(M | R)} (If) 条件判断"></a>IF {(M | R)} (If) 条件判断</h2><p>条件判断语句，必须与ENDIF 一起使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  IF ((FLD01=FLD02) </span><br><span class="line">		  OR (FLD01&gt;FLD03)) </span><br><span class="line">		  AND(FLD03=FLD04)</span><br><span class="line">		  处理语句</span><br><span class="line">		  ENDIF</span><br></pre></td></tr></table></figure>
<p>当条件判断成立时，才会执行下面的处理语句。<br>条件判断可以使用括号，OR，AND，来表达复杂的逻辑关系<br>IF 必须有对应的ENDIF，所以建议写程序时，写无IF 就加个ENDIF，然后再来写中间的处理语<br>句，以免遗漏。<br>IF 语句，还可以这种用法：<br>IF *IN(20)<br>ENDIF<br>这时，等价于<br>IF *IN20=’1’<br>ENDIF<br>IFxx (If) 条件判断<br>与ANDxx 类似，这是RPG 的语法，一行代码只能表示一个条件，如</p>
<p>Factory 1 Operation Factory 2 Result HI LO EQ<br>FLD01 IFEQ FLD02<br>FLD01 ORGT FLD03<br>处理语句<br>ENDIF<br>与AND 和ANDxx 类似，由于IF 语句在表达复杂的逻辑关系时更直观，所以通常我只使用IF，而<br>不是IFxx 了。</p>
<h2 id="ITER-Iterate-循环中，不处理此语句之后的语句"><a href="#ITER-Iterate-循环中，不处理此语句之后的语句" class="headerlink" title="ITER (Iterate) 循环中，不处理此语句之后的语句"></a>ITER (Iterate) 循环中，不处理此语句之后的语句</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1 		  DO 		10 		  N</span><br><span class="line">		  处理语句1</span><br><span class="line">		  IF 		条件判断</span><br><span class="line">		  ITER</span><br><span class="line">		  ENDIF</span><br><span class="line">		  处理语句2</span><br><span class="line">		  ENDDO</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1 		  DO 		10 		  N</span><br><span class="line">		  ITERTAG 	TAG</span><br><span class="line">		  处理语句1</span><br><span class="line">		  IF 		条件判断</span><br><span class="line">		  GOTO 		ITERTAG</span><br><span class="line">		  ENDIF</span><br><span class="line">		  处理语句2</span><br><span class="line">		  ENDDO</span><br></pre></td></tr></table></figure>
<p>不知道这个例子能不能让人明白，都是在说当条件判断成立时，就不执行处理语句2，直接从循环头开始处理。ITER 语句执行后，程序相当于跳转至循环体中的第一句，重新向下运行（即执行循环）。当有多层循环嵌套时，ITER 仅作用于最里层的循环。当循环中执行了子过程时，子过程中不能对该循环进行ITER 操作。也就是说：DO，ENDO，ITER 这些语句必须在一块（即要么都在主过程中，要么都在同一个子过程中）</p>
<h2 id="KFLD-Define-Parts-of-a-Key-定义组合键值中的字段"><a href="#KFLD-Define-Parts-of-a-Key-定义组合键值中的字段" class="headerlink" title="KFLD (Define Parts of a Key) 定义组合键值中的字段"></a>KFLD (Define Parts of a Key) 定义组合键值中的字段</h2><p>这个其实应该与KLIST 一起来讲，因为这两个操作是在一起使用的。一个PF 对应的逻辑文件LF，可能会有多个KEY 值，那么，我们要根据多个KEY 值，对于该逻辑文件进行查询定位操作时，就需要使用KLIST、KFLD 这两个操作码：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  FHSKEY	KLIST //定义组合键值FHSKEY</span><br><span class="line">		  KFLD 		FLD01 //组合键的首个字段为FLD01</span><br><span class="line">		  KFLD 		FLD02 //组合键的第二个字段FLD02</span><br></pre></td></tr></table></figure>
<p>组合键值的使用方式，就是将组合键视为一个变量，进行各种操作，如：<br>FHSKEY CHAIN FMTFHS<br>或 F<br>HSKEY SETLL FMTFHS<br>意思，就是说按组合键值，查询定位到逻辑文件PFFHSL3 中去。<br>这里要注意，PFFHSL3 的键值是FHS01、FHS02（即PF 文件中的字段），而程序中的组合键<br>值为FLD01、FLD02 两个程序中定义的变量，只要类型、长度与键值FHS01、FHS02相等即可。同<br>时，对文件进行查询定位操作后，在没有对FLD01、FLD02 赋值之前，这两个字段的值是不会发<br>生变化的（即不会更改组合键的键值）；但是，组合键中的字段，也可以直接定义为PF 文件中<br>的字段，如</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  FHSKEY 	KLIST</span><br><span class="line">		  KFLD 		FHS01</span><br><span class="line">		  KFLD 	    FHS02</span><br></pre></td></tr></table></figure>
<p>此时，可以将PF 文件中的字段FHS01、FHS02 先视为两个普通的变量，进行赋值，然后用<br>组合键FHSKEY 对PFFHSL3 进行查询定位；当执行完CHAIN，或READ 语句后，因为读取到了文件<br>中的数据，所以FHS01、FHS02 的值将发生变化，也即是组合键FHSKEY的键值发生了变化。基于<br>此，所以通常我不会将组合键的字段设置为查询文件中的字段，而是定义为几个独立的临时字<br>段，以免需要过于频繁的考虑键值的更改。</p>
<h2 id="KLIST-Define-a-Composite-Key-以上面的KFLD-操作码"><a href="#KLIST-Define-a-Composite-Key-以上面的KFLD-操作码" class="headerlink" title="KLIST (Define a Composite Key) 以上面的KFLD 操作码"></a>KLIST (Define a Composite Key) 以上面的KFLD 操作码</h2><h2 id="LEAVE-Leave-a-Do-Group-退出当前循环"><a href="#LEAVE-Leave-a-Do-Group-退出当前循环" class="headerlink" title="LEAVE (Leave a Do Group) 退出当前循环"></a>LEAVE (Leave a Do Group) 退出当前循环</h2><p>退出当前循环，语法和注意事项基本与“ITER”相同：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1 		  DO 		10 		  N</span><br><span class="line">处理语句1</span><br><span class="line">		  IF 		条件判断</span><br><span class="line">		  LEAVE</span><br><span class="line">		  ENDIF</span><br><span class="line">		  处理语句2</span><br><span class="line">		  ENDDO</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">1 		  DO 		10 		  N</span><br><span class="line">		  处理语句1</span><br><span class="line"></span><br><span class="line">		  IF 		条件判断</span><br><span class="line">		  GOTO 		LEAVETAG</span><br><span class="line">		  ENDIF</span><br><span class="line">		  处理语句2</span><br><span class="line">		  ENDDO</span><br><span class="line">		  LEAVE TAG</span><br></pre></td></tr></table></figure>
<p>这两个例子都是在说当条件判断成立时，就不执行剩余的循环体，直接跳出循环。LEAVE 语句执行后，程序相当于跳转至ENDDO 循环结束处，然后向下执行ENDDO之后的循环外的执行语句。当有多层循环嵌套时，LEAVE 仅作用于最里层的循环。当循环中执行了子过程时，子过程中不能对该循环进行LEAVE 操作。也就是说：DO，ENDO，LEAVE这些语句必须在一块（即要么都在主过程中，要么都在同一个子过程中）</p>
<h2 id="LOOKUP-Look-Up-a-Table-or-Array-Element-对数组的查询定位"><a href="#LOOKUP-Look-Up-a-Table-or-Array-Element-对数组的查询定位" class="headerlink" title="LOOKUP (Look Up a Table or Array Element) 对数组的查询定位"></a>LOOKUP (Look Up a Table or Array Element) 对数组的查询定位</h2><p>假设已定义数组DIMDATA，每条记录四位长，共三条记录的数组，且数组中已赋<br>值如下：<br>DIMDATA(1) = ‘0001’<br>DIMDATA(2) = ‘0002’<br>DIMDATA(3) = ‘0003’<br>那么，下面的语句就是对数组的查询定位操作：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  EVAL 		N=1</span><br><span class="line">		  &#x27;0002&#x27; 	LOOKUP 	  DIMDATA(N) 54</span><br></pre></td></tr></table></figure>
<p>首句N=1，表示从第一条记录开始查询；如果N=2，即表示从第2 条记录开始查询；如果N 大<br>于数组定义时的总记录数（如N=4），则下面的LOOKUP 语句会报错，跳出程序；<br>第二句，表示查询 数组DIMDATA 中，内容为’0002’的，是第几条记录；其中，54 为EQ 指示器。当找到记录时，打开指示器，*IN54 = ‘1’；当未找到记录时， 指示器处于关闭状态，*IN54=’0’。与操作码CHINA 的指示器含义刚好相反；<br>在这个例子中，执行完LOOKUP 语后，*IN54=’1’， N = 2（即数组DIMDATA 中，有内容<br>为’0002’的记录，是第二条记录。当数组中有多条内容相同的记录时，N 为顺序查询到的第<br>一条记录当数组中无相应记录时，*IN54=’0’, N = 初始值，此例中，即N = 1</p>
<h2 id="MOVE-Move-赋值语句"><a href="#MOVE-Move-赋值语句" class="headerlink" title="MOVE (Move) 赋值语句"></a>MOVE (Move) 赋值语句</h2><ol>
<li>基本语法：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">MOVE FLD01 FLD02</span><br><span class="line">FLD01、FLD02 可以是不同的类型。即允许一个为字符，一个为数字</span><br></pre></td></tr></table></figure></li>
<li>允许在MOVE 操作中，对Result 字符进行定义。</li>
<li>MOVE 操作码，使用右对齐赋值。所谓右对齐，即是将Factory 2 的最右边一个字符，赋值</li>
</ol>
<p>到Result 的最右边的一个字符；然后再将Factory 2 向左取一位字符，赋值到Result 从最右<br>边起，左移一位的字符是，依此类推。直到取完Factory 2 的值，或Result 已赋满值。<br>4. 由上述其实已可看出，MOVE 操作码在对字符赋值时，使用的是覆盖方式赋值。即如果FLD02<br>将在赋值的字符处，原来有值，将会将原来的值覆盖；如果已有值时，未执行赋值操作，将仍<br>然保留原值。<br>5. 当FLD01、FLD02 都为字符型：如果FLD01 的长度为5 位，FLD02 的长度为8 位。FLD01 的<br>内容为’12345’，FLD02的内容为’ABCDEFGH’，当执行了MOVE 操作后，FLD02 的内容为’<br>ABC12345’，可以看到，后5 位由’DEFGH’变成了FLD01 的’12345’，而前三位仍然保留原<br>来的值’ABC’；<br>要注意的是，在字符型变量中，空字符也会参与赋值。如果FLD01 的内容为’12 ‘，即后<br>三位是空时，那么执行MOVE 操作后，FLD02的值将会是’ABC12 ‘。看到了没有，最后三位也<br>与FLD01 一样，是空；而前三位FLD01的值保持不变，仍为’ABC’。反之，当FLD01 的长度为8<br>位，’12345678’,而FLD02 的长度为5 位’ABCDE’时，执行完MOVE 操作后，FLD02 的值为’<br>45678’，即从最右边开始，向左赋值；MOVE操作表示右对齐，空也算字符。<br>6. 数字赋值到字符的处理：<br>当FLD01 为数字（5，2），FLD02 为字符（8）时，MOVE 操作将会把数字的小数点去掉，<br>将数字转换为字符，右对齐赋值到字符变量中。数字型变量如果未满，前面都视为空，而不是0；<br>如果FLD01 为123.45 ， FLD02 为’ABCDEFGH’ ， 赋值之后，FLD02=’ABC12345’，首三位<br>保持FLD02 原有的值。如果FLD01=123.45，FLD02 原来为空， 赋值之后，FLD02=’ 12345’；<br>（字符型变量首三位保持原来的空值）如果FLD01=3.45，FLD02 原来为空， 赋值之后，FLD01=’<br>345’。 （数型变量未满足，前面也视为空，而不是0）如果数字的长度大于字符的长度，系统<br>将会自动从左边开始，将大于的部分截去。如FLD01 长度为10，2，等于12345678.90 时，赋值<br>后，FLD02 会等于’34567890’<br>7. 字符赋值到数字的处理：<br>当FLD01 为字符(8)，FLD02 为数字(5,2)时，MOVE 操作会将字符右对齐赋值到数字中，如<br>果字符后面有空，系统会自动做补零处理；如果FLD01 为’12345678’，FLD02 为0，赋值之后，<br>FLD02=456.78；如果FLD01 为’12345 ‘，即后三位为空时，赋值之后，FLD02=450.00，自动<br>补0；当数字长度大于字符的长度，如FLD02 为(10,2)时，数字最高位在赋值时，将会保持原值，<br>如FLD02=12345678.90 ， FLD01=’87654321’ ， 赋值之后，FLD02=12876543.21，注意最高<br>位的12 保持未变所以通常，字符转数字时，长度最好保持一致，以免得赋值时有意外。<br>8. 日期、时间型变量与字符、数字的转换<br>日期型变量与字符的转换，会带上分隔符。如果日期型变量为’2007-02-12’时，字符型<br>变量也需要定义为8+2 位，当执行完赋值操作时，字符型变量即为’2007-02-12’，注意，是<br>有分隔符的；时间型变量也一样，只是长度要需要6+2位。反之，当字符型变量赋值到日期型变<br>量中，也是需要有这个分隔符的；<br>日期型变量与数字的转换，将会自动去掉分隔符（非常好吧），如果日期型变量为’<br>2007-02-12’时，赋值到一个8 位的数字型变量，该变量就等于20070212；反之，数字赋值到</p>
<p>日期型变量中时，也是需要8 位纯数字；时间型变量也一样处理，只要长度需要为6 位。</p>
<h2 id="MOVEA-P-Move-Array-数组赋值"><a href="#MOVEA-P-Move-Array-数组赋值" class="headerlink" title="MOVEA {(P)} (Move Array) 数组赋值"></a>MOVEA {(P)} (Move Array) 数组赋值</h2><p>该操作码仅作用于数组。<br>假设已定义数组DIMDATA，每条记录二位长，共三条记录的数组，且数组中已赋值如下：<br>DIMDATA(1) = ‘01’<br>__ DIMDATA(2) = ‘02’<br>DIMDATA(3) = ‘03’<br>当执行完MOVEA 操作后：<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>MOVEA <em>BLANK DIMDATA<br>DIMDATA 中所有的要素都变成了空值。<br>MOVEA 还可以将一个变量拆分赋值到数组中，仍是上例，假设有一个6 位字符型变量 FLD01，<br>其值为’ABCDEF’，那么执行语句：<br>MOVEA FLD01 DIMDATA<br>后，数组中的值将是如下：<br>DIMDATA(1) = ‘AB’<br>DIMDATA(2) = ‘CD’<br>DIMDATA(3) = ‘EF’<br>当变量的长度，小于（数组单条记录长度</em>总记录数）时，超出部分的数组的值，保持原值。<br>仍是上例，假设FLD01 为4 位长的字符变量，值为’ABCD’时，执行MOVEA 操作后，数组中的<br>值如下：<br>DIMDATA(1) = ‘AB’<br>DIMDATA(2) = ‘CD’<br>DIMDATA(3) = ‘03’<br>注意，最后一个记录DIMDATA(3)的值仍保持原’03’不变，没有被清空。<br>MOVEL {(P)} (Move Left) 左对齐赋值语法<br>与MOVE 操作码相同，所不同的是对齐方式为左对齐，即是将Factory 2 的最左边一个字符，<br>赋值到Result 的最左边的一个字符；然后再将Factory 2 向右取一位字符，赋值到Result 从<br>最左边起，右移一位的字符，依此类推。直到取完Factory 2 的值，或Result 已赋满值。<br>在进行长度不同的字符之间赋值时，可按照上面这个原则，根据MOVE 操作码中的案例，想<br>想不同情况的结果，这里不做一一列举。<br>要注意的是，当使用MOVEL，由字符转为数字时，后面的空格会自动补0，如’123‘（后面<br>5 位都为空），转到数字型变量中，就变成了123000.00。因为大部分情况下，我们定义的标准，<br>都是字符型左对齐，数字型右对齐。所以此时字符转数字要注意，以免无端扩大倍数。</p>
<h2 id="MULT-H-Multiply-数学运算—乘"><a href="#MULT-H-Multiply-数学运算—乘" class="headerlink" title="MULT {(H)} (Multiply) 数学运算—乘"></a>MULT {(H)} (Multiply) 数学运算—乘</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  MULT      FLD02     FLD03</span><br></pre></td></tr></table></figure>
<p>等于<br>EVAL FLD03 = FLD01 * FLD02<br>可以对当前行对FLD03 进行定义；<br>Factory 1 可以不填写；<br>必须保证FLD03 的位数足够大，否则超长时，程序会报错异常退出。</p>
<h2 id="MVR-Move-Remainder-数学运算—除法运算取余"><a href="#MVR-Move-Remainder-数学运算—除法运算取余" class="headerlink" title="MVR (Move Remainder) 数学运算—除法运算取余"></a>MVR (Move Remainder) 数学运算—除法运算取余</h2><p>这个操作码，在讲操作码DIV 时，已讲过：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  DIV FLD02 FLD03</span><br><span class="line">MVR 	  FLD04</span><br></pre></td></tr></table></figure>
<p>当FLD01=11，FLD02=时4，<br>FLD03=2 （商）<br>FLD04=3 （余）</p>
<h2 id="OPEN-E-Open-File-for-Processing-打开文件"><a href="#OPEN-E-Open-File-for-Processing-打开文件" class="headerlink" title="OPEN {(E)} (Open File for Processing) 打开文件"></a>OPEN {(E)} (Open File for Processing) 打开文件</h2><p>Factory 1 Operation Factory 2 Result HI LO EQ<br>OPEN 文件名<br>OPEN 后面的对象，必须是在当前程序中已声明的文件名（不是文件的记录格式名），而且<br>在OPEN 操作之后，在程序结束之前之前，必须有对应的CLOSE 操作。使用OPEN 操作，文件在<br>声明时，必须使用USROPN 关键字（详见D 行说明）。</p>
<h2 id="ORxx-Or-逻辑判断—或"><a href="#ORxx-Or-逻辑判断—或" class="headerlink" title="ORxx (Or) 逻辑判断—或"></a>ORxx (Or) 逻辑判断—或</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  IFGT FLD03</span><br><span class="line">FLD01 	  OREQ FLD02</span><br></pre></td></tr></table></figure>
<p>等价于<br>IF FLD01&gt;FLD03 OR FLD01=FLD02<br>与IF、IFxx，AND、ANDxx 类似，RPGLE 的写法OR，比RPG 的写法ORxx 要灵活，<br>而且可以用来表达一些复杂的逻辑关系。有鉴于此，所以通常IF 语句中，我会以OR 为主，基<br>本不用ORxx。如果在编程序方面，公司/项目组无硬性要求，那我觉得还是少用ORxx 吧，总觉<br>得这种写法的逻辑关系看起来不直接，尤其是有很复杂的AND,OR 时。</p>
<h2 id="OTHER-Otherwise-Select-分支语句的判断"><a href="#OTHER-Otherwise-Select-分支语句的判断" class="headerlink" title="OTHER (Otherwise Select) 分支语句的判断"></a>OTHER (Otherwise Select) 分支语句的判断</h2><p>与分支语句SELECT 一起使用，表示不符合上述所有条件时的操作，如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  SELECT</span><br><span class="line">		  WHEN 		条件判断1</span><br><span class="line">		  处理语句1</span><br><span class="line">		  WHEN 		条件判断2</span><br><span class="line">		  处理语句2</span><br><span class="line">		  OTHER</span><br><span class="line">		  处理语句3</span><br><span class="line">		  ENDSL</span><br></pre></td></tr></table></figure>
<p>在这个例子中，当满足条件判断1 时，运行处理语句1，运行结束后跳至ENDSL 处；如果不<br>满足条件判断1，则程序继续向下执行，判断是否满足条件判断2。<br>当满足条件判断2 时，运行处理语句2，跳至ENDSL；当不满足<br>当不满足条件判断2 时，程序继续向下执下，当读到OTHER 操作码时，无条件运行处理语<br>句3（即当程序当前不满足以上所以条件判断时，则执行OTHER 之后的语句。<br>处理语句允许有很多句；条件判断可以写得很复杂，也允许对不同的字段进行判断；比如<br>说C 语言也有分支语句switch，但是这个语句只能对一个字段进行分支判断，ILE 语言与它不<br>同，允许对不同的字段进行判断就我目前掌握的测试情况，上述的SELECT—WHEN–OTHER—<br>ENDSL，其实也可以写做：<br>IF 条件判断1<br>处理语句1<br>ELSEIF 条件判断2<br>处理语句2<br>ELSE<br>处理语句3<br>ENDIF<br>即WHEN 与ELSEIF 是类似的，这样说，应该可以明白了吧。<br>总之，SELECT—ENDSL 是一个很好用的语法，尤其是在表示很多不同的分支处理时。</p>
<h2 id="READ-N-E-Read-a-Record-读取记录"><a href="#READ-N-E-Read-a-Record-读取记录" class="headerlink" title="READ {(N | E)} (Read a Record) 读取记录"></a>READ {(N | E)} (Read a Record) 读取记录</h2><ol>
<li><p>基本语法：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  READ      文件记录格式名 		45 46</span><br></pre></td></tr></table></figure>
<p>READ后面跟的，必须是声明的文件记录格式名；<br>LO 指示器表示锁表指示器，当在指定的时间（CHGPF，WAITRCD 项可看到），需要读取的<br>记录仍被锁，将会打开LO 指示器，即*IN45=’1’；<br>EQ指示器为是否读到指示器。当未读到任何记录时，打开EQ 指示器，即*IN46=’1’</p>
</li>
<li><p>当文件在程序中，是用只读的方式声明时，READ 操作并不会造成锁表；<br>如果文件在程序中是用修改的方式声明，READ 操作成功后，该记录被锁；直到执行解锁操作（UNLOCK，或UPDATE），或READ 该文件的其它记录，才会解锁<br>如果文件是用修改的方式声明，但希望READ 操作不锁表时，那么就用READ（N），<br>即 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  READ(N)   文件记录格式名 		45 46</span><br></pre></td></tr></table></figure>
<p>这样读文件，就不会锁记录，但是同时也不能修改记录。如果需要修改记录，那么在修改之前（包括对文件字段赋值之前），还必须再对该记录进行一次定位操作（比如CHAIN、READ 语句均可）。也就是说，如果要修改记录，必须先锁住当前记录。</p>
</li>
<li><p>当执行READ 操作时，程序是根据游标当前在文件中所指向的位置，顺序读取下一条记录。</p>
</li>
<li><p>执行READ 操作时，允许声明的文件没有键值。（即PF 文件）<br> READC {(E)} (Read Next Changed Record)<br> 读下一次修改过的记录<br> READE {(N | E)} (Read Equal Key) 读取键值相等的记录<br> 语法与READ 操作码大致一样，这里不再重复，只说不同的：<br> 假设程序中已声明逻辑文件PFFHSL3（键值为FHS01+FHS02）</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FHSKEY 	KLIST</span><br><span class="line">			KFLD	  FLD01</span><br><span class="line">			KFLD 	  FLD02</span><br><span class="line">FHSKEY 	SETLL 	  FMTFHS</span><br><span class="line">			DOW       1=1</span><br><span class="line">FHSKEY 	READE FMTFHS 15</span><br><span class="line">			IF 		  *IN15=’1’</span><br><span class="line">			LEAVE</span><br><span class="line">			ENDIF</span><br><span class="line">			ENDDO</span><br></pre></td></tr></table></figure>
<p>这段话的意思，就是定义组合键值FHSKEY，然后根据这个FHSKEY 在逻辑文件PFFHSL3 中去<br>定位，循环读取PFFHSL3 中，FHS01、FHS03 与FLD01、FLD02 相等的记录。<br>当读取记录结束，或键值不等时，退出循环（*IN15 是EQ 指示器）。如果将READE 操作码<br>换成READ 操作码的话（当然，Factory 1 处也就不能有值），就没有“键值不等时退出循环”<br>这一层意思，只是读不到记录时就退出循环，但有时我们使用逻辑文件，仅仅是需要它的排序，<br>而不需要读不到键值相等的记录就退出循环。<br>所以说，使用READ 操作码，还是READE 操作码，需要根据实际的要求来决定。以上的Factory<br>1 处填写值的系统处理，当READE 操作码在Factory 1 处未填写值时，系统实际上是将当前的<br>值与读到的上一条记录的关键字进行比较，而不是与SETLL 时的键值做比较（读第一条记录不做比较！），如果键值不等时，置EQ 指示器为1。也就是说，如果没有与FHSKEY 键值相同的录，<br>那么系统并不是直接找开EQ 指示器，而是会一直保持正常地往下读，直到找到与读到的第一条<br>记录关键字不同的记录，才会打开EQ 指示器，所以要注意。</p>
</li>
</ol>
<h2 id="READP-N-E-Read-Prior-Record-读取记录—游标上移"><a href="#READP-N-E-Read-Prior-Record-读取记录—游标上移" class="headerlink" title="READP {(N | E)} (Read Prior Record) 读取记录—游标上移"></a>READP {(N | E)} (Read Prior Record) 读取记录—游标上移</h2><p>简单来说，READ、READE 操作时，游标在数据文件中，是下移的；即读完第一条记录，游<br>标指向第二条记录；读完第二条记录，游标指向第三条记录，依此类推，直至最后一条记录。<br>但READP 则正好相反，游标是上移的，即读完第三条记录后，游标指向第二条记录；读完第二<br>条记录后，游标指向第一条记录，直至读完第一条记录。一般来说，用READ、READE 的概率会<br>比READP、READPE 的概率高得多，不过在某些情况下，使用READP 操作，又的确会很省事，大<br>家可在编程序时多实践。</p>
<h2 id="READPE-N-E-Read-Prior-Equal"><a href="#READPE-N-E-Read-Prior-Equal" class="headerlink" title="READPE {(N | E)} (Read Prior Equal)"></a>READPE {(N | E)} (Read Prior Equal)</h2><p>是指游标上移，按键值去读取文件。与READP 的关系，就类似于READE 与READ 的关系。</p>
<h2 id="RESET-E-Reset"><a href="#RESET-E-Reset" class="headerlink" title="RESET {(E)} (Reset)"></a>RESET {(E)} (Reset)</h2><p>将数据结构赋值成为初始值。<br>注意是初始值，不是清空。<br>如定义结构：<br>D FHSDS DS<br>D FHS01 10 INZ（’ABCD’）<br>D FHS02 5 INZ（’EFGH’）<br>那么，不管对该结构如何赋值，当执行语句：<br>C RESET FHSDS<br>之后，FHS01 将会变成’ABCD，FHS02 将会变成’EFGH’，即恢复成为初始值。</p>
<h2 id="RETURN-H-M-R-Return-to-Caller"><a href="#RETURN-H-M-R-Return-to-Caller" class="headerlink" title="RETURN {(H | M | R)} (Return to Caller)"></a>RETURN {(H | M | R)} (Return to Caller)</h2><p>RETURN 是程序结束。<br>在前面，“简单的程序流程”中，我们讲过，“SETON LR” 与RETURN 这两句话一起，做<br>为程序的结束。这里，再详细解释一下两者之间的区别，以及关系：如果不写RETURN，只写“SETON<br>LR”，程序执行完最后一句之后，将会再从第一句开始执行，造成死循环。<br>在简单的程序流程这个例子中，程序原来只想修改读到的第一条记录，而如果没有RETURN<br>的话，将会把所有的记录都修改掉，直到最后找不到可修改的记录，然后系统报错，异常中断。<br>如果只写RETURN，不打开指示器*INLR，根据blogliou 所说 “程序不会强制将内存中的数据写<br>到磁盘中。400 缺省的是BLOCK 输出，即数据记录满一个BLOCK 块时才会将这一组记录写到磁<br>盘上。那么如果这时BLOCK 没满，数据信息不会立刻写到磁盘上。之后有其它作业用到该文件，<br>读取的数据就不完整。”但如果文件有唯一键字，或记录日志，必须同步写时，其实BLOCK 实<br>际被忽略，也就是此时不会有错。</p>
<h2 id="ROLBK-E-Roll-Back"><a href="#ROLBK-E-Roll-Back" class="headerlink" title="ROLBK {(E)} (Roll Back)"></a>ROLBK {(E)} (Roll Back)</h2><ol>
<li>基本语法<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result</span><br><span class="line">ROLBK</span><br></pre></td></tr></table></figure></li>
<li>该操作码无其它参数，就是指对事务处理进行回滚操作。</li>
<li>ILE 程序中，ROLBK 操作可随时进行，也允许在没有声明COMMIT 类型的文件的情况下，仍<br>进行ROLBK 操作（对该进程这前的事务进行确认处理）</li>
</ol>
<h2 id="SCAN-E-Scan-Character-String-扫描字符串"><a href="#SCAN-E-Scan-Character-String-扫描字符串" class="headerlink" title="SCAN {(E)} (Scan Character String) 扫描字符串"></a>SCAN {(E)} (Scan Character String) 扫描字符串</h2><p>扫描字符或字符串Factory 1 在对象字符串Factory 2 中是否存在</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  SCAN 	    FLD02 	  N 		   26</span><br></pre></td></tr></table></figure>
<p>FLD01 可以是字符，也可以是字符变量；可以是一位长，也可以是多位长。<br>当FLD01 在FLD02 中存在时，EQ 指示器打开，即<em>IN26=’1’，同时将FLD02 中的起始位置，<br>赋值给N；<br>当FLD01 在FLD02 中不存在时，EQ 指示器保持关闭状态，即</em>IN26=’0’，同时N=0允许从<br>FLD02 中的指定位置开始检查：<br>FLD01 SCAN FLD02:2 N 26<br>如上句，即表示从FLD02 的第2 位，开始扫描。在实际使用中，比如说我们判断某个字符<br>是否为数字，就可以先定义一个0—9 的常量，然后将要判断的字符去SCAN 一下这个常量。<br>SELECT (Begin a Select Group) 分支语句<br>在操作码“OTHER”中讲过，为方便读者，列出简单语法如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">		  SELECT</span><br><span class="line">		  WHEN 条件判断1</span><br><span class="line">		  处理语句1</span><br><span class="line">		  WHEN 条件判断2</span><br><span class="line">		  处理语句2</span><br><span class="line">		  OTHER</span><br><span class="line">		  处理语句3</span><br><span class="line">		  ENDSL</span><br></pre></td></tr></table></figure>
<p>要注意，SELECT 操作码，必须有对应的ENDSL 操作码，否则编译无法通过。<br>SETGT {(E)} (Set Greater Than) 定位操作—大于<br>举个例子吧，假设文件中有一个字段，是标识顺序号的，1、2、3、4。即该字段为1，<br>表示第一条记录，该字段为2，表示第2 条记录。那么：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">2 SETGT 文件记录格式名</span><br><span class="line">READ 文件记录格式名</span><br></pre></td></tr></table></figure>
<p>这个READ 操作，READ 到的，是第3 条记录。也就是说，SETGT 操作码，会将游标定位到<br>大于键值的第一条记录前。在实际使用中，如果我们是按逻辑文件读取，而且读了一条记录之<br>后，对其键值相同的记录都不需要再读取时，就可以用SETGT，不过需要注意，Factory 1 项，<br>需要是与键值相同的变量，即如果文件是使用多个字段做为键值，那么我们也需要先定义一个<br>组合键值的变量，然后Factory 1 处填写这个组合键值的变量名。<br>当声明文件的键值有多项时，Factory 1 项的键值，允许小于文件的键值，但顺序必须一<br>致。即声明的文件如果键值为：FHS01、FHS02、FHS03，那么我们在程序中定义三个类型与之相<br>同的变量FLD01、FLD02、FLD03，以下写法都是有效的<br>FLDKEY KLIST<br>KFLD FLD01<br>KFLD FLD02<br>KFLD FLD03<br>FLDKEY SETGT 文件记录格式名<br>FLDKEY KLIST<br>KFLD FLD01<br>KFLD FLD02<br>FLDKEY SETGT 文件记录格式名<br>FLD01 SETLL 文件记录格式名</p>
<h2 id="SETLL-E-Set-Lower-Limit-定位操作—小于语法"><a href="#SETLL-E-Set-Lower-Limit-定位操作—小于语法" class="headerlink" title="SETLL {(E)} (Set Lower Limit) 定位操作—小于语法"></a>SETLL {(E)} (Set Lower Limit) 定位操作—小于语法</h2><p>与SETGT 相同，含义与SETGT 不同。SETLL 操作码，会将游标定位到与键值相等的第一条<br>记录之前，仍是上例，如果是<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>2 SETLL 文件记录格式名<br>READ 文件记录格式名<br>那么READ 操作码读到的记录，就是第2 条记录，看到了吧，和SETGT 不同。<br>SETLL 操作码还可以用来简单判断当前键值是否存在有记录，以PFFHSL3 为例（键值为FHS01、<br>FHS02）<br>Factory 1 Operation Factory 2 Result HI LO EQ<br>FHSKEY KLIST<br>KFLD FLD01<br>KFLD FLD02<br>EVAL FLD01=’01’<br>EVAL FLD02=’02’</p>
<p>FHSKEY SETLL 文件记录格式名 44<br>当文件中有相应记录时，EQ 指示器打开，即<em>IN44=’1’<br>当文件中无相应记录时，EQ 指示器关闭，即</em>IN44=’0’（与CHAIN 正好相反，要注意）而在<br>这种用法中，SETLL 与CHAIN 的区别在于，CHAIN 是定位读取了记录，而SETLL仅仅只是判断该<br>记录是否存在。所以用SETLL 操作，不能修改记录，也无法取出记录的值。只能判断记录是否<br>存在。如果要修改记录，或取出记录的值，还需要有一个读取定位的操作，如READ，或READE、<br>READP 等（最常用的，应该就是READ 操作）</p>
<h2 id="SETOFF-Set-Indicator-Off-关闭指示器"><a href="#SETOFF-Set-Indicator-Off-关闭指示器" class="headerlink" title="SETOFF (Set Indicator Off) 关闭指示器"></a>SETOFF (Set Indicator Off) 关闭指示器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">SETOFF 10 11 12</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">EVAL *IN10=’0’</span><br><span class="line">EVAL *IN11=’0’</span><br><span class="line">EVAL *IN12=’0’</span><br></pre></td></tr></table></figure>
<p>在SETOFF 这个操作码中，指示器填在HI、LO、EQ 哪里都没关系，都是表示要被关闭的指示器</p>
<h2 id="SETON-Set-Indicator-On-打开指示器"><a href="#SETON-Set-Indicator-On-打开指示器" class="headerlink" title="SETON (Set Indicator On) 打开指示器"></a>SETON (Set Indicator On) 打开指示器</h2><p>Factory 1 Operation Factory 2 Result HI LO EQ<br>SETOFF 10 11 12<br>等价于<br>EVAL *IN10=’1’<br>EVAL *IN11=’1’<br>EVAL *IN12=’1’<br>在SETON 这个操作码中，指示器填在HI、LO、EQ 哪里都没关系，都是表示要被关闭的指示器<br>SORTA (Sort an Array)<br>数组排序</p>
<h2 id="SQRT-H-Square-Root-开方"><a href="#SQRT-H-Square-Root-开方" class="headerlink" title="SQRT {(H)} (Square Root) 开方"></a>SQRT {(H)} (Square Root) 开方</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">9 SQRT 3 N</span><br></pre></td></tr></table></figure>
<p>这时，N=3（因为3 的平方为9）<br>9、3 都可以是数字型变量，或者直接是数字</p>
<h2 id="SUB-H-Subtract-减法操作"><a href="#SUB-H-Subtract-减法操作" class="headerlink" title="SUB {(H)} (Subtract) 减法操作"></a>SUB {(H)} (Subtract) 减法操作</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 SUB FLD02 FLD03</span><br><span class="line">SUB FLD02 FLD03</span><br></pre></td></tr></table></figure>
<h2 id="SUBDUR-E-Subtract-Duration-日期相减"><a href="#SUBDUR-E-Subtract-Duration-日期相减" class="headerlink" title="SUBDUR {(E)} (Subtract Duration) 日期相减"></a>SUBDUR {(E)} (Subtract Duration) 日期相减</h2><ol>
<li>减日期<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  SUBDUR    N:*Y      FLD02</span><br></pre></td></tr></table></figure>
表示将日期型变量FLD01 减去N 年，赋值到日期型变量FLD02 中；<br>N 可以是一个数字型变量，也可以就是一个数字，N 允许为负数<br>*Y，*M，*D（还有其它的参数值，可见ADDDUR，其中有详细解释）</li>
<li>判断两个日期型变量之间的天/月/年数<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FLD01 	  SUBDUR    FLD02 N:*D</span><br></pre></td></tr></table></figure>
这时，N 做为一结果变量，表示日期型变量FLD01 与FLD02 之间的天数</li>
</ol>
<h2 id="SUBST-P-E-Substring-取字符-字符串"><a href="#SUBST-P-E-Substring-取字符-字符串" class="headerlink" title="SUBST {(P | E)} (Substring) 取字符/字符串"></a>SUBST {(P | E)} (Substring) 取字符/字符串</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">2 SUBST FLD01:3 FLD02</span><br></pre></td></tr></table></figure>
<p>表示从字段FLD01 的第3 位开始，取2 位，左对齐赋值到字段FLD02 中。<br>要求字段FLD01 的长度必须大于或等于3+2 位，否则程序会报错。<br>可以尝试用%SUBST 语句，也是等价的，如下<br>EVAL FLD02=%SUBST(FLD01:3:2)<br>表示的是同样的意思。<br>起始位数3，取的长度2，在两种写法之下，都可以使用数字型变量来表达。<br>相比较之下，%SUBST 还有一种用法，就是对字符的指定位置赋值，这个就厉害了：<br>EVAL %SUBST(FLD02:3:2)=’01’<br>看到了吧，这句话就是说，使字段FLD02 的第3、4 位（即从第三位开始，两位长）等于“01”<br>TAG (Tag) 定义标签，与GOTO 同用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">FHSTAG TAG</span><br><span class="line">TESTN (Test Numeric)</span><br><span class="line">检查字段是否全是数字</span><br><span class="line">TESTZ (Test Zone)</span><br><span class="line">测试区位</span><br><span class="line">TIME (Time of Day) --取当前系统时间</span><br><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">TIME FLD01</span><br><span class="line">FLD01 可以是时间型或数字型变量</span><br><span class="line">UNLOCK &#123;(E)&#125; (Unlock a Data Area or Release a Record) 解锁</span><br><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">UNLOCK 文件记录格式名</span><br><span class="line"></span><br><span class="line">UNLOCK 是解锁操作，在某种程度上，可以将UNLOCK 视为ROLBK，将UPDATE视为COMMIT。即</span><br><span class="line">如果锁定某条记录，并对其字段进行赋值之后，使用UPDATE 语句，将会把修改后的结果保存下</span><br><span class="line">来，即修改文件，而UNLOCK 语句则不会修改文件，即否认了之前对文件字段做的赋值修改。</span><br><span class="line">从程序的执行效率上来讲，UNLOCK 的执行效率是高于UPDATE 的，因为UPDATE操作时，系</span><br><span class="line">统需要对文件的每一个字段进行确认处理(DEBUG 时可以看到)，而UNLOCK 就是简单的解锁而</span><br><span class="line">已。</span><br><span class="line"></span><br><span class="line">## UPDATE (Modify Existing Record) 修改记录</span><br><span class="line"></span><br><span class="line">这里需要说明一下，在执行UPDATE 的时候，必须先使用READ、CHAIN 等操作码锁定一条记录。如果未锁住记录，UPDATE 操作码将会报错。当执行了UNLOCK、UPDATE、以及ROLBK 语句时，等于是解锁，此时再执行UPDATE 操作码之前，必须再次锁住记录操作；</span><br><span class="line"></span><br><span class="line">## WHEN &#123;(M | R)&#125; (When) 分支判断语句中的条件判断</span><br><span class="line"></span><br><span class="line">在操作码“OTHER”，“SELECT”中都讲过，仍列出简单语法如下：</span><br></pre></td></tr></table></figure>
<p>Factory 1 Operation Factory 2 Result HI LO EQ<br>SELECT<br>WHEN 条件判断1<br>处理语句1<br>WHEN 条件判断2<br>处理语句2<br>OTHER<br>处理语句3<br>ENDSL</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">## WHENxx (When True Then Select)</span><br><span class="line"></span><br><span class="line">上面的语法，是RPGLE 的语法，WHENxx 是RPG 的语法，也就是</span><br><span class="line">SELECT</span><br><span class="line">FLD01 WHENEQ FLD02</span><br><span class="line">处理语句1</span><br><span class="line">……..</span><br><span class="line">这样的语法，在表达复杂的逻辑关系时，必须与ANDxx，ORxx 一起使用，所以我不</span><br><span class="line">使用WHENxx 这个操作码。</span><br><span class="line"></span><br><span class="line">## WRITE (Create New Records) 写记录</span><br><span class="line"></span><br><span class="line">常用的方式：</span><br></pre></td></tr></table></figure>
<p>Factory 1 Operation Factory 2 Result HI LO EQ<br>          CLEAR     文件记录格式名<br>          EVAL      文件字段1=xxxx<br>          EVAL      文件字段2=xxxx<br>          WRITE     文件记录格式名</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">表示在文件中写入一条新记录。文件需要声明为可写的</span><br><span class="line"></span><br><span class="line">通常会在给文件字段赋值之前，作一次CLEAR 操作来进行初始化，以避免不必要的麻烦。</span><br><span class="line"></span><br><span class="line">## XFOOT &#123;(H)&#125; (Sum the Elements of an Array)</span><br><span class="line"></span><br><span class="line">对数组字段的累加统计。</span><br><span class="line">假设DIMDATA 定义为一个数字型的数组变量，FHS01 为一个足够大的数字型变量</span><br><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">XFOOT DIMDATA FHS01</span><br><span class="line">就表示将数组DIMDATA 中的所有记录的值都取出来，汇总相加，赋值到数字变量FHS01 中</span><br><span class="line"></span><br><span class="line">## XLATE &#123;(P | E)&#125; (Translate)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">将一个字符串中指定的字符，更换成另外的字符。</span><br><span class="line">举例：如MYCHAR1， MYCHAR2 都是两个20 位长的字符型变量</span><br></pre></td></tr></table></figure>
<p>Factory 1 Operation Factory 2 Result HI LO EQ<br>MOVEL ‘ABCAAAC123’ MYCHAR1<br>‘A’:’9’ XLATE MYCHAR1 MYCHAR2</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">执行过这个语句之后，MYCHAR2 就等于”9BC999C123’，即将字符串MYCHAR1 中所有的“A”都</span><br><span class="line">变成了“9”；XLATE 也可能指定起始位置。如上句更改为：</span><br><span class="line">&#x27;A&#x27;:&#x27;9&#x27; XLATE MYCHAR1：4 MYCHAR2</span><br><span class="line">则MYCHAR2 等于“ABC999C123”，指从第4 位开始（含第4 位），将“A”变成“9”赋值。</span><br><span class="line"></span><br><span class="line">## Z-ADD &#123;(H)&#125; (Zero and Add) 向数字型变量赋值</span><br></pre></td></tr></table></figure>
<p>Factory 1 Operation Factory 2 Result HI LO EQ<br>Z-ADD FLD01 FLD02</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">将数字型变量FLD01，赋值到数字型变量FLD02 中。</span><br><span class="line">Z-ADD、MOVE 虽然同是赋值操作码，但Z-ADD 的用法就远没有MOVE 那么变化多</span><br><span class="line">端，只能在数字型变量之间赋值。所以也没有什么可说的了。zero</span><br><span class="line">如果要对数字型变量赋初值，使用\*ZERO</span><br><span class="line">Z-ADD \*ZERO FLD02</span><br><span class="line"></span><br><span class="line">## Z-SUB &#123;(H)&#125; (Zero and Subtract) 用0 减</span><br><span class="line"></span><br><span class="line">Factory 1 Operation Factory 2 Result HI LO EQ</span><br><span class="line">Z-SUB FLD01 FLD02</span><br><span class="line">等价于</span><br><span class="line">0 SUB FLD01 FLD02</span><br><span class="line">等价于</span><br><span class="line">EVAL FLD02=FLD01*(-1)</span><br><span class="line"></span><br><span class="line">## *ALL</span><br><span class="line"></span><br><span class="line">\*ALL 是个很有意义的变量，举例：</span><br></pre></td></tr></table></figure>
<p>EVAL FLD01=*ALL’0’</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">表示将字符型变量FLD01 赋值为全’0’</span><br><span class="line">而CLOSE *ALL就表示关闭所有文件，意义与上面是不同的</span><br><span class="line"></span><br><span class="line">## ％LEN</span><br><span class="line"></span><br><span class="line">取字符串的长度，举例：</span><br><span class="line">(MYLEN 为数字型变量，FLD01 为字符型变量)</span><br></pre></td></tr></table></figure>
<p>EVAL MYLEN = %LEN(FLD01)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">这句话的意思，是指取字符串FLD01 的长度，不过通常这样用是没意义的，因为直接用%LEN</span><br><span class="line">操作码，取到的是字符串的总长度，不是有效字符的长度，也就是说FLD01 长度为2，那么MYLEN</span><br><span class="line">就恒等于2，不会变。就算变量FLD01 中没有值，取出的MYLEN 也等于2.。所以，%LEN 通常会</span><br><span class="line">与%TRIM 或是%TRIMR 一起使用，语法在下面介绍。</span><br><span class="line"></span><br><span class="line">## %TRIM，%TRIMR</span><br><span class="line"></span><br><span class="line">都是去字符串变量中的空字符意思，%TRIM 是去字符串左边的空字符；%TRIMR 是去字符串</span><br><span class="line">右边的空格。通常我们在写程序中，都是默认字符串变量左对齐，所以我们使用%TRIMR 操作码</span><br><span class="line">的概率应该高一点。举例：</span><br></pre></td></tr></table></figure>
<p>EVAL MYLEN = %LEN(%TRIMR(FLD01))</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">这时的MYLEN，就是指变量FLD01 中的有效长度（前提条件是FLD01 中如果有值，是左对齐）。</span><br><span class="line">如果FLD01 为空，那么MYFLEN 为0；如果FLD01 首位有值，第二位为空，那么MYLEN 为1；如果</span><br><span class="line">FLD01 两位都不为空，那么MYLEN 就等于2。如果字符串左对齐，那么就使用%TRIMR还有一种用</span><br><span class="line">法，假设字符串FLD04 为4 位长的字符，FLD01，FLD02 都是2 位长的字符，且FLD01 等于“A ”，</span><br><span class="line">FLD02 等于“BC”，那我们执行：</span><br></pre></td></tr></table></figure>
<p>EVAL FLD04 = FLD01 + FLD01 + FLD02</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">FLD04 就等于“A A ”，也就是第二位与第四位都是空的，最后加的FLD02 其实无效。而</span><br><span class="line">如果执行</span><br></pre></td></tr></table></figure>
<p>EVAL FLD04 = %TRIMR(FLD01) + %TRIMR(FLD01) + FLD02</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">则FLD04 就等于“AABC”，也就是说，在这里，%TRIMR(FLD01)，是等价于单字符“A”的</span><br><span class="line"></span><br><span class="line">## MONITOR</span><br><span class="line"></span><br><span class="line">监控程序信息。据说是可以屏蔽掉出错信息，避免程序异常中断，未经测试。</span><br></pre></td></tr></table></figure></article><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/AS-400/">AS/400</a></div><div class="post_share"><div class="social-share" data-image="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" data-sites="wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://s2.loli.net/2022/08/21/Ay5sujrkH1nLTwW.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s2.loli.net/2022/08/21/Ay5sujrkH1nLTwW.jpg" alt="Wechat"/></a><div class="post-qr-code-desc">Wechat</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/54d95d51/"><img class="prev-cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">cl控制语言</div></div></a></div><div class="next-post pull-right"><a href="/posts/a83ba4eb/"><img class="next-cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">RPG-F行说明</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/b9ff8872/" title="10.21笔记"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-10-27</div><div class="title">10.21笔记</div></div></a></div><div><a href="/posts/881792ef/" title="10.22笔记"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-10-27</div><div class="title">10.22笔记</div></div></a></div><div><a href="/posts/9421881e/" title="AS&#x2F;400事务和日志"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-10-12</div><div class="title">AS&#x2F;400事务和日志</div></div></a></div><div><a href="/posts/6b557ec5/" title="AS&#x2F;400(二)"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-23</div><div class="title">AS&#x2F;400(二)</div></div></a></div><div><a href="/posts/6e639b06/" title="AS400(一)"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-22</div><div class="title">AS400(一)</div></div></a></div><div><a href="/posts/167fb41b/" title="AS&#x2F;400的历史"><img class="cover" src= "" data-lazy-src="https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-19</div><div class="title">AS&#x2F;400的历史</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "" data-lazy-src="https://s2.loli.net/2022/08/20/hk9Zvq4YRsIcnrw.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">樱桃先生</div><div class="author-info__description">樱桃先生的博客小站</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">78</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">65</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">21</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://ytblogpic.oss-cn-guangzhou.aliyuncs.com/typoraWechat.jpeg"><i class="fab fa-weixin"></i><span>加为好友</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎光临樱桃小窝🍒～评论系统日常崩溃，没有找到长期稳定好用的组件。</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#RPG%E6%93%8D%E4%BD%9C%E7%A0%81%E6%B1%87%E6%80%BB"><span class="toc-number">1.</span> <span class="toc-text">RPG操作码汇总</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#ACQ-E-Acquire"><span class="toc-number">1.1.</span> <span class="toc-text">ACQ {(E)} (Acquire)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ADDDUR-E-Add-Duration-%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4%E7%9B%B8%E5%8A%A0"><span class="toc-number">1.2.</span> <span class="toc-text">ADDDUR {(E)} (Add Duration) 日期时间相加</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ANDxx-And-%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E8%AF%AD%E5%8F%A5%E2%80%94%E2%80%9C%E4%B8%8E%E2%80%9D"><span class="toc-number">1.3.</span> <span class="toc-text">ANDxx (And) 条件判断语句—“与”</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#BEGSR-Beginning-of-Subroutine-%E5%AD%90%E8%BF%87%E7%A8%8B%E7%9A%84%E5%BC%80%E5%A7%8B%E5%A4%84"><span class="toc-number">1.4.</span> <span class="toc-text">BEGSR (Beginning of Subroutine) 子过程的开始处</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CALL-E-Call-a-Program-%E8%B0%83%E7%94%A8%E5%A4%96%E9%83%A8%E7%A8%8B%E5%BA%8F"><span class="toc-number">1.5.</span> <span class="toc-text">CALL {(E)} (Call a Program) 调用外部程序</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CASxx-Conditionally-Invoke-Subroutine-%E5%B8%A6%E6%9D%A1%E4%BB%B6%E7%9A%84%E8%B0%83%E7%94%A8%E5%AD%90%E8%BF%87%E7%A8%8B"><span class="toc-number">1.6.</span> <span class="toc-text">CASxx (Conditionally Invoke Subroutine) 带条件的调用子过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CAT-P-Concatenate-Two-Character-Strings-%E5%AD%97%E7%AC%A6%E8%BF%9E%E6%8E%A5"><span class="toc-number">1.7.</span> <span class="toc-text">CAT {(P)} (Concatenate Two Character Strings) 字符连接</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CHAIN-N-E-Random-Retrieval-from-a-File-%E6%8C%89%E9%94%AE%E5%80%BC%E5%AF%B9%E6%96%87%E4%BB%B6%E8%AE%B0%E5%BD%95%E8%BF%9B%E8%A1%8C%E6%9F%A5%E8%AF%A2%E5%AE%9A%E4%BD%8D"><span class="toc-number">1.8.</span> <span class="toc-text">CHAIN {(N | E)} (Random Retrieval from a File) 按键值对文件记录进行查询定位</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CHECK-E-Check-Characters-%E6%A3%80%E6%9F%A5%E5%AF%B9%E8%B1%A1%E5%8F%98%E9%87%8F%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6"><span class="toc-number">1.9.</span> <span class="toc-text">CHECK {(E)} (Check Characters) 检查对象变量中的字符</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CHECKR-E-Check-Reverse-%E5%8F%8D%E5%90%91%E6%A3%80%E6%9F%A5%E5%AF%B9%E8%B1%A1%E5%8F%98%E9%87%8F%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6"><span class="toc-number">1.10.</span> <span class="toc-text">CHECKR {(E)} (Check Reverse) 反向检查对象变量中的字符</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CLEAR-Clear-%E6%B8%85%E9%99%A4%E5%86%85%E5%AE%B9"><span class="toc-number">1.11.</span> <span class="toc-text">CLEAR (Clear) 清除内容</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CLOSE-E-Close-Files-%E5%85%B3%E9%97%AD%E6%96%87%E4%BB%B6"><span class="toc-number">1.12.</span> <span class="toc-text">CLOSE {(E)} (Close Files) 关闭文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#COMMIT-E-Commit-%E6%97%A5%E5%BF%97%E4%BA%8B%E5%8A%A1%E5%A4%84%E7%90%86%E7%9A%84%E7%A1%AE%E8%AE%A4%E6%93%8D%E4%BD%9C"><span class="toc-number">1.13.</span> <span class="toc-text">COMMIT {(E)} (Commit) 日志事务处理的确认操作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#COMP-Compare-%E6%AF%94%E8%BE%83"><span class="toc-number">1.14.</span> <span class="toc-text">COMP (Compare) 比较</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DEFINE-Field-Definition"><span class="toc-number">1.15.</span> <span class="toc-text">DEFINE (Field Definition)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DELETE-E-Delete-Record"><span class="toc-number">1.16.</span> <span class="toc-text">DELETE {(E)} (Delete Record)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DIV-H-Divide-%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97%E2%80%94%E9%99%A4"><span class="toc-number">1.17.</span> <span class="toc-text">DIV {(H)} (Divide) 数学运算—除</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DO-Do-%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.18.</span> <span class="toc-text">DO (Do) 循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DOU-M-R-Do-Until-%E8%BF%98%E6%98%AF%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.19.</span> <span class="toc-text">DOU {(M | R)} (Do Until) 还是循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DOUxx-Do-Until-%E5%8F%88%E6%98%AF%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.20.</span> <span class="toc-text">DOUxx (Do Until) 又是循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DOW-M-R-Do-While-%E5%BE%AA%E7%8E%AF%EF%BC%8C%E5%8F%88%E8%A7%81%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.21.</span> <span class="toc-text">DOW {(M | R)} (Do While) 循环，又见循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DSPLY-E-Display-Function-%E5%B1%8F%E5%B9%95%E6%98%BE%E7%A4%BA"><span class="toc-number">1.22.</span> <span class="toc-text">DSPLY {(E)} (Display Function) 屏幕显示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#EVAL-H-M-R-Evaluation-%E8%B5%8B%E5%80%BC%E8%AF%AD%E5%8F%A5"><span class="toc-number">1.23.</span> <span class="toc-text">EVAL {(H | M | R)} (Evaluation) 赋值语句</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Factory-1-Operation-Factory-2-Result-HI-LO-EQ"><span class="toc-number">1.24.</span> <span class="toc-text">Factory 1 Operation Factory 2 Result HI LO EQ</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#EXSR-Invoke-Subroutine-%E6%89%A7%E8%A1%8C%E5%AD%90%E8%BF%87%E7%A8%8B"><span class="toc-number">1.25.</span> <span class="toc-text">EXSR (Invoke Subroutine) 执行子过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#EXTRCT-E-Extract-Date-Time-%E5%8F%96%E6%97%A5%E6%9C%9F%E3%80%81%E6%97%B6%E9%97%B4%E5%9E%8B%E5%8F%98%E9%87%8F%E4%B8%AD%E7%9A%84%E5%85%B7%E4%BD%93%E5%86%85%E5%AE%B9"><span class="toc-number">1.26.</span> <span class="toc-text">EXTRCT {(E)}(Extract Date&#x2F;Time) 取日期、时间型变量中的具体内容</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#FOR-For-%E5%8F%88%E6%98%AF%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.27.</span> <span class="toc-text">FOR (For) 又是循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#IF-M-R-If-%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD"><span class="toc-number">1.28.</span> <span class="toc-text">IF {(M | R)} (If) 条件判断</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ITER-Iterate-%E5%BE%AA%E7%8E%AF%E4%B8%AD%EF%BC%8C%E4%B8%8D%E5%A4%84%E7%90%86%E6%AD%A4%E8%AF%AD%E5%8F%A5%E4%B9%8B%E5%90%8E%E7%9A%84%E8%AF%AD%E5%8F%A5"><span class="toc-number">1.29.</span> <span class="toc-text">ITER (Iterate) 循环中，不处理此语句之后的语句</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#KFLD-Define-Parts-of-a-Key-%E5%AE%9A%E4%B9%89%E7%BB%84%E5%90%88%E9%94%AE%E5%80%BC%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5"><span class="toc-number">1.30.</span> <span class="toc-text">KFLD (Define Parts of a Key) 定义组合键值中的字段</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#KLIST-Define-a-Composite-Key-%E4%BB%A5%E4%B8%8A%E9%9D%A2%E7%9A%84KFLD-%E6%93%8D%E4%BD%9C%E7%A0%81"><span class="toc-number">1.31.</span> <span class="toc-text">KLIST (Define a Composite Key) 以上面的KFLD 操作码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#LEAVE-Leave-a-Do-Group-%E9%80%80%E5%87%BA%E5%BD%93%E5%89%8D%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.32.</span> <span class="toc-text">LEAVE (Leave a Do Group) 退出当前循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#LOOKUP-Look-Up-a-Table-or-Array-Element-%E5%AF%B9%E6%95%B0%E7%BB%84%E7%9A%84%E6%9F%A5%E8%AF%A2%E5%AE%9A%E4%BD%8D"><span class="toc-number">1.33.</span> <span class="toc-text">LOOKUP (Look Up a Table or Array Element) 对数组的查询定位</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MOVE-Move-%E8%B5%8B%E5%80%BC%E8%AF%AD%E5%8F%A5"><span class="toc-number">1.34.</span> <span class="toc-text">MOVE (Move) 赋值语句</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MOVEA-P-Move-Array-%E6%95%B0%E7%BB%84%E8%B5%8B%E5%80%BC"><span class="toc-number">1.35.</span> <span class="toc-text">MOVEA {(P)} (Move Array) 数组赋值</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MULT-H-Multiply-%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97%E2%80%94%E4%B9%98"><span class="toc-number">1.36.</span> <span class="toc-text">MULT {(H)} (Multiply) 数学运算—乘</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MVR-Move-Remainder-%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97%E2%80%94%E9%99%A4%E6%B3%95%E8%BF%90%E7%AE%97%E5%8F%96%E4%BD%99"><span class="toc-number">1.37.</span> <span class="toc-text">MVR (Move Remainder) 数学运算—除法运算取余</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#OPEN-E-Open-File-for-Processing-%E6%89%93%E5%BC%80%E6%96%87%E4%BB%B6"><span class="toc-number">1.38.</span> <span class="toc-text">OPEN {(E)} (Open File for Processing) 打开文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ORxx-Or-%E9%80%BB%E8%BE%91%E5%88%A4%E6%96%AD%E2%80%94%E6%88%96"><span class="toc-number">1.39.</span> <span class="toc-text">ORxx (Or) 逻辑判断—或</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#OTHER-Otherwise-Select-%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5%E7%9A%84%E5%88%A4%E6%96%AD"><span class="toc-number">1.40.</span> <span class="toc-text">OTHER (Otherwise Select) 分支语句的判断</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#READ-N-E-Read-a-Record-%E8%AF%BB%E5%8F%96%E8%AE%B0%E5%BD%95"><span class="toc-number">1.41.</span> <span class="toc-text">READ {(N | E)} (Read a Record) 读取记录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#READP-N-E-Read-Prior-Record-%E8%AF%BB%E5%8F%96%E8%AE%B0%E5%BD%95%E2%80%94%E6%B8%B8%E6%A0%87%E4%B8%8A%E7%A7%BB"><span class="toc-number">1.42.</span> <span class="toc-text">READP {(N | E)} (Read Prior Record) 读取记录—游标上移</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#READPE-N-E-Read-Prior-Equal"><span class="toc-number">1.43.</span> <span class="toc-text">READPE {(N | E)} (Read Prior Equal)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RESET-E-Reset"><span class="toc-number">1.44.</span> <span class="toc-text">RESET {(E)} (Reset)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RETURN-H-M-R-Return-to-Caller"><span class="toc-number">1.45.</span> <span class="toc-text">RETURN {(H | M | R)} (Return to Caller)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ROLBK-E-Roll-Back"><span class="toc-number">1.46.</span> <span class="toc-text">ROLBK {(E)} (Roll Back)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SCAN-E-Scan-Character-String-%E6%89%AB%E6%8F%8F%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">1.47.</span> <span class="toc-text">SCAN {(E)} (Scan Character String) 扫描字符串</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SETLL-E-Set-Lower-Limit-%E5%AE%9A%E4%BD%8D%E6%93%8D%E4%BD%9C%E2%80%94%E5%B0%8F%E4%BA%8E%E8%AF%AD%E6%B3%95"><span class="toc-number">1.48.</span> <span class="toc-text">SETLL {(E)} (Set Lower Limit) 定位操作—小于语法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SETOFF-Set-Indicator-Off-%E5%85%B3%E9%97%AD%E6%8C%87%E7%A4%BA%E5%99%A8"><span class="toc-number">1.49.</span> <span class="toc-text">SETOFF (Set Indicator Off) 关闭指示器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SETON-Set-Indicator-On-%E6%89%93%E5%BC%80%E6%8C%87%E7%A4%BA%E5%99%A8"><span class="toc-number">1.50.</span> <span class="toc-text">SETON (Set Indicator On) 打开指示器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SQRT-H-Square-Root-%E5%BC%80%E6%96%B9"><span class="toc-number">1.51.</span> <span class="toc-text">SQRT {(H)} (Square Root) 开方</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SUB-H-Subtract-%E5%87%8F%E6%B3%95%E6%93%8D%E4%BD%9C"><span class="toc-number">1.52.</span> <span class="toc-text">SUB {(H)} (Subtract) 减法操作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SUBDUR-E-Subtract-Duration-%E6%97%A5%E6%9C%9F%E7%9B%B8%E5%87%8F"><span class="toc-number">1.53.</span> <span class="toc-text">SUBDUR {(E)} (Subtract Duration) 日期相减</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SUBST-P-E-Substring-%E5%8F%96%E5%AD%97%E7%AC%A6-%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">1.54.</span> <span class="toc-text">SUBST {(P | E)} (Substring) 取字符&#x2F;字符串</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/posts/4995/" title="顺德好友小聚"><img src= "" data-lazy-src="https://ytblogpic.oss-cn-guangzhou.aliyuncs.com/blog-common.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="顺德好友小聚"/></a><div class="content"><a class="title" href="/posts/4995/" title="顺德好友小聚">顺德好友小聚</a><time datetime="2023-05-07T13:41:30.660Z" title="更新于 2023-05-07 21:41:30">2023-05-07</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/51438/" title="旅游归来的周末"><img src= "" data-lazy-src="https://ytblogpic.oss-cn-guangzhou.aliyuncs.com/blog-common.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="旅游归来的周末"/></a><div class="content"><a class="title" href="/posts/51438/" title="旅游归来的周末">旅游归来的周末</a><time datetime="2023-05-06T06:06:54.933Z" title="更新于 2023-05-06 14:06:54">2023-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/34851/" title="与好友的广西之旅"><img src= "" data-lazy-src="https://ytblogpic.oss-cn-guangzhou.aliyuncs.com/blog-common.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="与好友的广西之旅"/></a><div class="content"><a class="title" href="/posts/34851/" title="与好友的广西之旅">与好友的广西之旅</a><time datetime="2023-05-02T08:08:36.497Z" title="更新于 2023-05-02 16:08:36">2023-05-02</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/36794/" title="信用卡业务汇总"><img src= "" data-lazy-src="https://s2.loli.net/2022/08/22/kpfRHFaCWDTNAu1.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="信用卡业务汇总"/></a><div class="content"><a class="title" href="/posts/36794/" title="信用卡业务汇总">信用卡业务汇总</a><time datetime="2023-05-02T06:30:21.691Z" title="更新于 2023-05-02 14:30:21">2023-05-02</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/53652/" title="项目管理笔记"><img src= "" data-lazy-src="https://ytblogpic.oss-cn-guangzhou.aliyuncs.com/blog-common.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="项目管理笔记"/></a><div class="content"><a class="title" href="/posts/53652/" title="项目管理笔记">项目管理笔记</a><time datetime="2023-05-02T06:29:26.948Z" title="更新于 2023-05-02 14:29:26">2023-05-02</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://gitee.com/Xyingtao/blogimage/raw/master/img/AS400.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By 樱桃先生</div><div class="footer_custom_text">一切都是最好的安排</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><div class="js-pjax"><script>(()=>{
  const init = () => {
    twikoo.init(Object.assign({
      el: '#twikoo-wrap',
      envId: 'https://twikoo-seven-fawn.vercel.app',
      region: '',
      onCommentLoaded: function () {
        btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
      }
    }, null))
  }

  const getCount = () => {
    const countELement = document.getElementById('twikoo-count')
    if(!countELement) return
    twikoo.getCommentsCount({
      envId: 'https://twikoo-seven-fawn.vercel.app',
      region: '',
      urls: [window.location.pathname],
      includeReply: false
    }).then(function (res) {
      countELement.innerText = res[0].count
    }).catch(function (err) {
      console.error(err);
    });
  }

  const runFn = () => {
    init()
    
  }

  const loadTwikoo = () => {
    if (typeof twikoo === 'object') {
      setTimeout(runFn,0)
      return
    } 
    getScript('https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js').then(runFn)
  }

  if ('Twikoo' === 'Twikoo' || !true) {
    if (true) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
    else loadTwikoo()
  } else {
    window.loadOtherComment = () => {
      loadTwikoo()
    }
  }
})()</script></div><script>window.addEventListener('load', () => {
  const changeContent = (content) => {
    if (content === '') return content

    content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
    content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
    content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
    content = content.replace(/<[^>]+>/g,"") // remove html tag

    if (content.length > 150) {
      content = content.substring(0,150) + '...'
    }
    return content
  }

  const getComment = () => {
    const runTwikoo = () => {
      twikoo.getRecentComments({
        envId: 'https://twikoo-seven-fawn.vercel.app',
        region: '',
        pageSize: 6,
        includeReply: true
      }).then(function (res) {
        const twikooArray = res.map(e => {
          return {
            'content': changeContent(e.comment),
            'avatar': e.avatar,
            'nick': e.nick,
            'url': e.url + '#' + e.id,
            'date': new Date(e.created).toISOString()
          }
        })

        saveToLocal.set('twikoo-newest-comments', JSON.stringify(twikooArray), 10/(60*24))
        generateHtml(twikooArray)
      }).catch(function (err) {
        const $dom = document.querySelector('#card-newest-comments .aside-list')
        $dom.innerHTML= "无法获取评论，请确认相关配置是否正确"
      })
    }

    if (typeof twikoo === 'object') {
      runTwikoo()
    } else {
      getScript('https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js').then(runTwikoo)
    }
  }

  const generateHtml = array => {
    let result = ''

    if (array.length) {
      for (let i = 0; i < array.length; i++) {
        result += '<div class=\'aside-list-item\'>'

        if (true) {
          const name = 'data-lazy-src'
          result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
        }
        
        result += `<div class='content'>
        <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
        <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
        </div></div>`
      }
    } else {
      result += '没有评论'
    }

    let $dom = document.querySelector('#card-newest-comments .aside-list')
    $dom.innerHTML= result
    window.lazyLoadInstance && window.lazyLoadInstance.update()
    window.pjax && window.pjax.refresh($dom)
  }

  const newestCommentInit = () => {
    if (document.querySelector('#card-newest-comments .aside-list')) {
      const data = saveToLocal.get('twikoo-newest-comments')
      if (data) {
        generateHtml(JSON.parse(data))
      } else {
        getComment()
      }
    }
  }

  newestCommentInit()
  document.addEventListener('pjax:complete', newestCommentInit)
})</script><script src="/js/jquery.min.js"></script><div class="aplayer no-destroy" data-id="5225697049" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="false" data-mini="true" data-lrctype="-1"> </div><script src="https://cdn.jsdelivr.net/gh/xiabo2/CDN@latest/fishes.js"></script><link rel="stylesheet" href="/css/utils.css"><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/hijiki.model.json"},"display":{"position":"right","width":170,"height":280},"mobile":{"show":true},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/","tagMode":false});</script></body></html>